C++windows内核编程笔记day06 代码创建菜单

来源:互联网 发布:淘宝销量排行榜2015 编辑:程序博客网 时间:2024/06/05 18:43

创建菜单:
HMENU CreateMenu(VOID);
添加菜单项:
BOOL AppendMenu(  HMENU hMenu,         // handle to menu
  UINT uFlags,         // menu-item options
  UINT_PTR uIDNewItem, // identifier, menu, or submenu
  LPCTSTR lpNewItem    // menu-item content
  );
 uFlags:
    MF_POPUP  -有子菜单的菜单项目,uIDNewItem要设置为子菜单的句柄(转换为uint)
    MF_SEPARATOR -分隔线
    MF_STRING    -一般菜单项,被点击后会发送消息 WM_COMMAND
    MF_MENUBREAK -换一列

把菜单加到窗口:
BOOL SetMenu(  HWND hWnd,  // handle to window  HMENU hMenu // handle to menu
);
//修改菜单的勾选状态
DWORD CheckMenuItem(  HMENU hmenu,        // handle to menu
  UINT uIDCheckItem,  // menu item to check or uncheck
  UINT uCheck         // menu item options
  );
uCheck:
    MF_BYCOMMAND  -填写菜单id
    MF_BYPOSITION -填写菜单索引
    MF_CHECKED/MF_UNCHECKED //1/0 --是否选中

//触发菜单点击事件
case WM_COMMAND:
    On_Command(hwnd,wparam);
    break;
//点击事件处理
void On_Command(HWND hwnd,WPARAM wparam)
{
    bool IsFromMenu=(HIWORD(wparam)==0?true:false);//点击菜单:0,加速键:1
    unsigned int id=LOWORD(wparam);//被点的控件id
    switch(id)
    {
    case 10011:
        //MessageBox(NULL,"打开","info",MB_OK);
        if(isChecked)
        {
            CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_UNCHECKED);isChecked=false;
        }
        else{  CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_CHECKED);isChecked=true;
        //MessageBox(NULL,"1","info",MB_OK);
        }
        break;
    }
}
//设置可用或不可用,与CheckMenuItem用法一样
BOOL EnableMenuItem(HMENU hMenu,// handle to menu
  UINT uIDEnableItem,  // menu item to update
  UINT uEnable         // options
  );
WM_INITMENUPOPUP  //弹出菜单在被点击还未弹出来之前触发的消息
LRESULT CALLBACK WindowProc(
  HWND hwnd,       // handle to window
  UINT uMsg,       // WM_INITMENUPOPUP
  WPARAM wParam,   // handle to menu (HMENU)
  LPARAM lParam    // item position and indicator
);
lParam:
    LOWORD  被点击菜单的索引
    HIWORD  将要显示的菜单是否为窗口菜单(弹出式菜单不属于窗口菜单)

系统菜单的操作,消息:WM_SYSCOMMAND,不太重要,一般不用。
HMENU GetSystemMenu(  HWND hWnd,    // handle to window
  BOOL bRevert  // 是否返回默认菜单
  );
  AppendMenu //前面用过
 //删除菜单,根据位置删除时,删除前一个,后面一个会改变位置。
 BOOL DeleteMenu(  HMENU hMenu,     // handle to menu
  UINT uPosition,  // menu item identifier or position
  UINT uFlags      // option(MF_BYPOSITION/MF_BYCOMMAND)
  );

右键菜单:弹出式菜单,前面用过,这里主要在右键时显示菜单。
BOOL TrackPopupMenu(
  HMENU hMenu,         // handle to shortcut menu
  UINT uFlags,         // options
  int x,               // horizontal position
  int y,               // vertical position
  int nReserved,       // reserved, must be zero
  HWND hWnd,           // handle to owner window
  CONST RECT *prcRect  // ignored
);
uFlags:
    TPM_RETURNCMD  -点击菜单项,不发出WM_COMMAND消息,但有返回值(被点击菜单的ID)

//右键消息处理函数,也可以在WM_CONTEXTMENU消息中处理(专门处理)
//WM_CONTEXTMENU 在 WM_RBUTTONUP之后触发的
//WM_CONTEXTMENU 中的坐标不需要转换
void OnRButtonUp(HWND hwnd,LPARAM lparam)
{
    HMENU menucontext=CreatePopupMenu();
    AppendMenu(menucontext,MF_STRING,103,"查看");
    AppendMenu(menucontext,MF_STRING,104,"放大");
    AppendMenu(menucontext,MF_STRING,105,"缩小");
    POINT pt={0};
    pt.y=HIWORD(lparam);
    pt.x=LOWORD(lparam);
    ClientToScreen(hwnd,&pt);//将客户区坐标转换为相对于屏幕的坐标
    int cmdid= TrackPopupMenu(menucontext,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RETURNCMD,pt.x,pt.y,0,
        hwnd,NULL);//在鼠标位置显示菜单
    char txt[30]={0};
    sprintf(txt,"被点的菜单ID:%d\n",cmdid);
    MessageBox(hwnd,txt,"info",MB_OK);
}

ScreenToClient();//坐标转换函数


代码示例:

同样创建win32 application

主要cpp代码修改为:

// win32app.cpp : Defines the entry point for the application.//#include "stdafx.h"#include <stdio.h>HINSTANCE g_hinstance=0;//全局句柄HMENU menu1=0,menu2=0;HANDLE g_houtput=0;void OnCreate(HWND hwnd,LPARAM lparam){HMENU menu=CreateMenu();menu1=CreatePopupMenu();AppendMenu(menu1,MF_STRING|MF_CHECKED,10011,"打开");AppendMenu(menu1,MF_STRING,10012,"保存");AppendMenu(menu1,MF_SEPARATOR,0,NULL);AppendMenu(menu1,MF_STRING|MF_MENUBREAK,10013,"退出");menu2=CreatePopupMenu();AppendMenu(menu2,MF_STRING,10021,"复制");AppendMenu(menu2,MF_STRING|MF_GRAYED,10022,"粘贴");AppendMenu(menu,MF_POPUP,(UINT)menu1,"文件");AppendMenu(menu,MF_SEPARATOR,0,NULL);AppendMenu(menu,MF_POPUP,(UINT)menu2,"编辑");SetMenu(hwnd,menu);   HMENU menusys=GetSystemMenu(hwnd,FALSE);   for(int i=0;i<6;i++)   {  // DeleteMenu(menusys,0,MF_BYPOSITION);//删除系统菜单项   }   AppendMenu(menusys,MF_STRING,101,"我的菜单");}LRESULT CALLBACK OnInitMunuPopUp(HWND hwnd,       // handle to windowUINT uMsg,       // WM_INITMENUPOPUPWPARAM wParam,   // handle to menu (HMENU)LPARAM lParam    // item position and indicator){unsigned int index=LOWORD(lParam);int IsWindowMenu=HIWORD(lParam);char txt[200]={0};sprintf(txt,"OnInitMenuPopUp:menu:%d,Index:%d,IsWindow:%d\n",wParam,index,IsWindowMenu);WriteConsole(g_houtput,txt,strlen(txt),NULL,NULL);return 0;}bool isChecked=true;void On_Command(HWND hwnd,WPARAM wparam){bool IsFromMenu=(HIWORD(wparam)==0?true:false);unsigned int id=LOWORD(wparam);switch(id){case 10011://MessageBox(NULL,"打开","info",MB_OK);if(isChecked){CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_UNCHECKED);isChecked=false;}else{  CheckMenuItem(menu1,id,MF_BYCOMMAND|MF_CHECKED);isChecked=true;//MessageBox(NULL,"1","info",MB_OK);}break;}}void OnSysCommand(HWND hwnd,WPARAM wparam){bool IsFromMenu=(HIWORD(wparam)==0?true:false);unsigned int id=LOWORD(wparam);switch(id){case 101:MessageBox(hwnd,"我的菜单","info",MB_OK);break;default://MessageBox(hwnd,"我的菜单1","info",MB_OK);break;}}void OnRButtonUp(HWND hwnd,LPARAM lparam){// HMENU menucontext=CreatePopupMenu();// AppendMenu(menucontext,MF_STRING,103,"查看");// AppendMenu(menucontext,MF_STRING,104,"放大");// AppendMenu(menucontext,MF_STRING,105,"缩小");// POINT pt={0};// pt.y=HIWORD(lparam);// pt.x=LOWORD(lparam);// ClientToScreen(hwnd,&pt);//将客户区坐标转换为相对于屏幕的坐标// int cmdid= TrackPopupMenu(menucontext,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RETURNCMD,pt.x,pt.y,0,// hwnd,NULL);//在鼠标位置显示菜单// char txt[30]={0};// sprintf(txt,"被点的菜单ID:%d\n",cmdid);// MessageBox(hwnd,txt,"info",MB_OK);}void OnContextMenu(HWND hwnd,LPARAM lparam){ HMENU menucontext=CreatePopupMenu(); AppendMenu(menucontext,MF_STRING,103,"查看"); AppendMenu(menucontext,MF_STRING,104,"放大"); AppendMenu(menucontext,MF_STRING,105,"缩小"); POINT pt={0}; pt.y=HIWORD(lparam); pt.x=LOWORD(lparam); //ClientToScreen(hwnd,&pt);//将客户区坐标转换为相对于屏幕的坐标 int cmdid= TrackPopupMenu(menucontext,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RETURNCMD,pt.x,pt.y,0, hwnd,NULL);//在鼠标位置显示菜单if(cmdid!=0){ char txt[30]={0}; sprintf(txt,"被点的菜单ID:%d\n",cmdid); MessageBox(hwnd,txt,"info",MB_OK);}}//回调函数LRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam){switch(msg){case WM_SYSCOMMAND:if(wparam==SC_CLOSE){int ret=MessageBox(NULL,"是否退出","info",MB_YESNO);if(ret==IDYES){//下面代码会自动关闭和销毁//PostQuitMessage(0);}else return 0;//不执行下面代码}OnSysCommand(hwnd,wparam);break;//在创建窗口之后还未显示的时候case WM_CREATE:OnCreate(hwnd,lparam);break;case WM_DESTROY:PostQuitMessage(0);break;case WM_COMMAND:On_Command(hwnd,wparam);break;case WM_INITMENUPOPUP:OnInitMunuPopUp(hwnd,msg,wparam,lparam);break;case WM_RBUTTONUP:OnRButtonUp(hwnd,lparam);break;case WM_CONTEXTMENU:OnContextMenu(hwnd,lparam);break;}return DefWindowProc(hwnd,msg,wparam,lparam);}//注册窗口类BOOL Register(LPSTR lpClassName,WNDPROC wndproc){WNDCLASSEX wce={0};wce.cbSize=sizeof(wce);wce.cbClsExtra=200;wce.cbWndExtra=200;wce.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);wce.hCursor=NULL;wce.hIcon=NULL;wce.hIconSm=NULL;wce.hInstance=g_hinstance;wce.lpfnWndProc=wndproc;wce.lpszClassName=lpClassName;wce.lpszMenuName=NULL;wce.style=CS_HREDRAW|CS_VREDRAW;ATOM atom= RegisterClassEx(&wce);if(atom==0){MessageBox(NULL,"注册失败","info",MB_OK);return FALSE;}return TRUE;}//创建窗口HWND CreateMain(LPSTR lpClassName,LPSTR lpWndName){HWND hwnd=CreateWindowEx(0,lpClassName,lpWndName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,g_hinstance,"hello create");return hwnd;}//创建子窗口HWND CreateChild(HWND phwnd,LPSTR lpClassName,LPSTR lpWndName){if(Register(lpClassName,DefWindowProc)==0){MessageBox(phwnd,"创建子窗口失败","info",MB_OK);return NULL;}//子窗口风格,都要 WS_CHILD|WS_VISIBLEHWND hwnd=CreateWindowEx(0,lpClassName,lpWndName,WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,200,200,phwnd,NULL,g_hinstance,NULL);return hwnd;}//显示窗口void Display(HWND hwnd){ShowWindow(hwnd,SW_SHOW);UpdateWindow(hwnd);}//处理消息void MSGdeal(){MSG msg={0};while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);//翻译消息 DispatchMessage(&msg);//派发给 WinProc 处理消息 }}int APIENTRY WinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPSTR     lpCmdLine,                     int       nCmdShow){AllocConsole();//调试程序方法g_houtput=GetStdHandle(STD_OUTPUT_HANDLE);g_hinstance=hInstance; // TODO: Place code here.if(Register("main",WinProc)==0){MessageBox(NULL,"注册失败","提示",MB_OK);return 0;}HWND hwnd= CreateMain("main","pro1");Display(hwnd);MSGdeal();return 0;}






0 0
原创粉丝点击