博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
windows编程之菜单操作
阅读量:7116 次
发布时间:2019-06-28

本文共 9968 字,大约阅读时间需要 33 分钟。

分清几个概念

<1>“主菜单” 和 “顶层菜单” 是一个意思。

<2>主菜单中的项目叫做 “弹出菜单” 或者 “子菜单”。

<3>弹出菜单的项目能够是另外一个弹出菜单。

<4>菜单的状态:启用,禁用。无效化,无效化跟前两者的差别是灰色显示文字。

 

(1)菜单消息

<1>WM_INITMENU

wParam,   // handle to menu (HMENU)        lParam    // not used

<2>WM_MENUSELECT

菜单项被选中的时候

wParam,   // menu item (UINT) and flags (UINT)       lParam    //handle to menu (HMENU)

当中

LOWORD(wParam)		//被选中项目:菜单ID或者弹出式菜单句柄HIWORD(wParam)		//选择旗标

旗标是MF_GRAYED、MF_DISABLED、MF_CHECKED、MF_BITMAP、MF_POPUP、MF_HELP、MF_SYSMENU和MF_MOUSESELECT的集合。

<3>WM_INITMENUPOPUP

 当下拉菜单被激活的时候就会发出这种消息

WPARAM wParam,   // handle to menu (HMENU)LPARAM lParam    // item position and indicator
LOWORD(lParam)代表的是菜单项索引,HIWORD(lParam)表示的是TRUE,或者FALSE,菜单是系统菜单的时候表示的TRUE,非系统菜单的时候表示的是FALSE。

<4>WM_COMMAND

表示使用者已经从菜单中选择了一个被启用的菜单项,

LOWORD (wParam):菜单命令ID

HIWORD(wParam):0

lParam:0

<5>WM_MENUCHAR

(2)菜单项中的字母的下划线

把字母前面加&字符,就能够出现字母下划线的效果,当用Alt键+ 字符,能够快捷的弹出子菜单,或者运行菜单项命令。

相应属性

(3)菜单项的选中和去选中状态

CheckMenuItem(hMenu, iSelection, MF_UNCHECKED) ;CheckMenuItem(hMenu, iSelection, MF_CHECKED) ;

(4)关于Menu的函数

         关于菜单的操作从大体方向上看无外乎增删改查四种操作。

4.1    HMENUCreateMenu(VOID);

4.2   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_BITMAP。MF_OWNERDRAW,MF_STRING

演示样例:

AppendMenu         (hMenuPopup, MF_STRING, IDM_APP_EXIT,"E&xit") ;

AppendMenu         (hMenu, MF_POPUP, hMenuPopup,"&File") ;

4.3    BOOLInsertMenu(  HMENU hMenu,          // handle to menu

                         UINT uPosition,       // item that new item precedes

                         UINT uFlags,          // options

                         UINT_PTR uIDNewItem,  // identifier, menu, or submenu

                         LPCTSTR lpNewItem     // menu item content);

这个函数和AppendMenu相比除了uPosition这个參数外,其余全然同样

uPosition:表示被插的位置索引或者菜单ID,详细是哪一个取决于uFlags中是MF_BYCOMMAND还是MF_BYPOSITION。

uIDNewItem:插入项是命令项的时候表示的是ID,插入项是菜单的时候表示的菜单句柄。

lpNewItem:    插入项的内容,详细取决于uFlags中包括的MF_BITMAP。MF_STRING。MF_OWNERDRAW

 

注意:不能放在一起的命令组合

  • MF_BYCOMMAND and MF_BYPOSITION
  • MF_DISABLED, MF_ENABLED, and MF_GRAYED
  • MF_BITMAP, MF_STRING, MF_OWNERDRAW, and MF_SEPARATOR
  • MF_MENUBARBREAK and MF_MENUBREAK
  • MF_CHECKED and MF_UNCHECKED

4.4    BOOLInsertMenuItem(  HMENU hMenu,           // handle to menu

                UINT uItem,            // identifier or position

                BOOL fByPosition,      // meaning of uItem

                LPCMENUITEMINFO lpmii  // menu item information);

 
typedef struct tagMENUITEMINFO {  UINT    cbSize;   UINT    fMask;   UINT    fType;   UINT    fState;   UINT    wID;   HMENU   hSubMenu;   HBITMAP hbmpChecked;   HBITMAP hbmpUnchecked;   ULONG_PTR dwItemData;   LPTSTR  dwTypeData;   UINT    cch;   HBITMAP hbmpItem;} MENUITEMINFO, *LPMENUITEMINFO;

4.5   BOOL RemoveMenu(  HMENU hMenu,     // handle to menu

                UINT uPosition, // menu item identifier or position

                UINT uFlags     // options);

4.6    BOOLModifyMenu(  HMENU hMnu,           // handle to menu

                UINT uPosition,       // menu item to modify 

                   UINTuFlags,          // options

                UINT_PTR uIDNewItem,  // identifier, menu, or submenu

                 LPCTSTR lpNewItem     // menu item content);

4.7    BOOLDeleteMenu(  HMENU hMenu,     // handle to menu

                UINT uPosition,  // menu item identifier or position

                UINT uFlags      // option);

删除菜单项,假设菜单项时弹出菜单。那么就会释放菜单句柄所指向的内存。

4.7    BOOLDrawMenuBar(  HWND hWnd  // handle to window);

4.8    HMENUGetSubMenu(  HMENU hMenu,  // handle to menu

                         int nPos      // menu item position);

当菜单条发生变化时候。必须调用这个函数又一次绘制菜单//常常验证。未必

(6)右键菜单

右键菜单跟一般的菜单没什么差别。仅仅是弹出的时候。须要用到这个函数

BOOLTrackPopupMenu(  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_CENTERALIGN。TMP_LEFTALIGN。TMP_RIGHTALIGN

TPM_BOTTOMALIGN, TPM_TOPALIGN, TPM_VCENTERALIGN

TPM_LEFTBUTTPON,TPM_RIGHTBUTTON

TPM_NONOTIFY, TPM_RETURNCMD

(7)系统菜单

获取系统菜单句柄

HMENU GetSystemMenu( 

         HWNDhWnd,    // handle to window

       BOOL bRevert  // reset option);

当中bRevert = FALSE时候。表示。复制系统的菜单,而且返回复制菜单的句柄,这个菜单能够进行改动。当bRevert = TRUE 时,设置系统菜单为默认的原始状态。而且函数返回值是NULL.

 (8) 加速键

加速键也是一种资源,它能够使用快捷键迅速的打开命令项。加速键 能够在在资源中自己加入,也能够直接使用程序编写。

加速键中基本的改变的code有

while(GetMessage(&msg,NULL,0,0))

{
if (!TranslateAccelerator(hWnd,hAccel,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

在这里 TranslateAccelerator函数把 一些按键消息翻译成WM_COMMAND,或者WM_SYSCOMMAND消息。

(9)代码演示样例

一下演示样例是一个全然依靠code不依赖创建资源的菜单demo,当中包括菜单条。右键菜单,系统菜单,加速键能够对菜单进行动态的改动,删除。加入操作。

#define OEMRESOURCE# include
#define IDM_FILE_OPEN 100#define IDM_FILE_NEW 101#define IDM_FILE_PIC 102#define IDM_FILE_EXIT 103#define IDM_MENU_ADD 104#define IDM_MENU_REM 105#define IDM_MENU_DEL 106#define IDM_MENU_MOD 107#define IDM_ABOUT 108#define IDM_VERSION 109#define IDM_MENU_NEW 110#define IDM_POP_ONE 200#define IDM_POP_TWO 201#define IDM_SYS_ONE 300#define IDM_SYS_TWO 301LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);HMENU createOwnMenu(HWND hwnd);HMENU createPopMenu(HWND hwnd);HACCEL createAccelerator(HWND hwnd);TCHAR* szAppName = TEXT("MenuClass");TCHAR* szWndName = TEXT("ChangeMenu");HACCEL hAccel = NULL;int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int iCmdShow){ WNDCLASS wndCls; HWND hWnd; MSG msg; wndCls.cbClsExtra = 0; wndCls.cbWndExtra = 0; wndCls.lpfnWndProc = WndProc; wndCls.style = CS_HREDRAW | CS_VREDRAW; wndCls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndCls.hCursor = LoadCursor(NULL,IDC_ARROW); wndCls.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndCls.hInstance = hInstance; wndCls.lpszClassName = szAppName; wndCls.lpszMenuName = NULL; if(!RegisterClass(&wndCls)) { MessageBox(NULL,TEXT("Register window failed"),TEXT("Error"),MB_OK); } hWnd = CreateWindow(szAppName,szWndName,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL); UpdateWindow(hWnd); ShowWindow(hWnd,SW_NORMAL); while(GetMessage(&msg,NULL,0,0)) { if(!TranslateAccelerator(hWnd,hAccel,&msg)) TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){ static int nAdd = 1; HMENU hMenu,hSonMenu,hTmpMenu; HMENU hTrack,hSon; HMENU hSysMenu; POINT pt; switch(msg) { case WM_CREATE: hMenu = createOwnMenu(hwnd); SetMenu(hwnd,hMenu); hSysMenu = GetSystemMenu(hwnd,FALSE); AppendMenu(hSysMenu,MF_SEPARATOR,0,NULL); AppendMenu(hSysMenu,MF_STRING,IDM_SYS_ONE,TEXT("SysOne")); AppendMenu(hSysMenu,MF_STRING,IDM_SYS_TWO,TEXT("SysTwo")); hAccel = createAccelerator(hwnd); break; case WM_SYSCOMMAND: switch(LOWORD(wParam)) { case IDM_SYS_ONE: MessageBox(NULL,TEXT("This is added system menu item1"),NULL,MB_OK); break; case IDM_SYS_TWO: MessageBox(NULL,TEXT("This is added system menu item2"),NULL,MB_OK); break; } break; case WM_COMMAND: hMenu = GetMenu(hwnd); switch(LOWORD(wParam)) { case IDM_FILE_OPEN: MessageBox(NULL,TEXT("File Open selected"),TEXT("Test check"),MB_OK); break; case IDM_MENU_ADD: hTmpMenu = GetSubMenu(hMenu,2); AppendMenu(hTmpMenu,MF_STRING,IDM_MENU_NEW+nAdd,TEXT("New Item")); nAdd++; DrawMenuBar(hwnd); break; case IDM_MENU_REM: hTmpMenu = GetSubMenu(hMenu,2); if( nAdd >1 ) { nAdd--; RemoveMenu(hTmpMenu,IDM_MENU_NEW+nAdd,MF_BYCOMMAND); } // 当菜单项时弹出菜单的时候,只切断弹出菜单跟所属菜单的联系,但不销毁对象 /*GetSubMenu(hTmpMenu,2); RemoveMenu(hTmpMenu,2,MF_BYPOSITION);*/ DrawMenuBar(hwnd); break; case IDM_MENU_MOD: hTmpMenu = GetSubMenu(hMenu,2); ModifyMenu(hTmpMenu,0,MF_BYPOSITION,IDM_ABOUT,TEXT("Modified Item")); DrawMenuBar(hwnd); break; case IDM_MENU_DEL: hTmpMenu = GetSubMenu(hMenu,2); DeleteMenu(hTmpMenu,2,MF_BYPOSITION); DrawMenuBar(hwnd); break; } break; case WM_RBUTTONDOWN: hTrack = createPopMenu(hwnd); hSon = GetSubMenu(hTrack,0); pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); ClientToScreen(hwnd,&pt); TrackPopupMenu(hSon,TPM_LEFTBUTTON| TPM_RIGHTALIGN,pt.x,pt.y,0,hwnd,NULL); break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hwnd,msg,wParam,lParam);}HMENU createOwnMenu(HWND hwnd){ HMENU hMenu = CreateMenu(); HMENU hPopMenu = CreateMenu(); //MF_BYPOSIOTION,MF_BYCOMMAND is not useful here in AppendMenu AppendMenu(hPopMenu,MF_STRING|MF_CHECKED|MF_GRAYED,IDM_FILE_OPEN,TEXT("&Open")); InsertMenu(hPopMenu,0,MF_BYPOSITION|MF_STRING|MF_DISABLED,IDM_FILE_NEW,TEXT("&New")); HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE); HBITMAP hBmp = (HBITMAP)LoadImage(hInstance,TEXT("bitmap1.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE); AppendMenu(hPopMenu,MF_BITMAP,IDM_FILE_PIC,(LPCWSTR)hBmp); AppendMenu(hPopMenu,MF_SEPARATOR,NULL,NULL); AppendMenu(hPopMenu,MF_STRING,IDM_FILE_EXIT,TEXT("&Exit")); SetMenuItemBitmaps(hPopMenu,IDM_FILE_PIC,MF_BYCOMMAND,hBmp,hBmp); AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPopMenu,TEXT("File")); hPopMenu = CreateMenu(); AppendMenu(hPopMenu,MF_STRING,IDM_MENU_ADD,TEXT("&Add")); AppendMenu(hPopMenu,MF_STRING,IDM_MENU_REM,TEXT("&Remove")); AppendMenu(hPopMenu,MF_STRING,IDM_MENU_MOD,TEXT("&Modify")); AppendMenu(hPopMenu,MF_STRING,IDM_MENU_DEL,TEXT("&Delete")); AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPopMenu,TEXT("Menu")); hPopMenu = CreateMenu(); AppendMenu(hPopMenu,MF_STRING,IDM_ABOUT,TEXT("About")); AppendMenu(hPopMenu,MF_STRING,IDM_VERSION,TEXT("Version")); HMENU hSonMenu = CreateMenu(); AppendMenu(hSonMenu,MF_STRING,IDM_MENU_NEW,TEXT("Son")); AppendMenu(hPopMenu,MF_POPUP,(UINT_PTR)hSonMenu,TEXT("Son Menu")); AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPopMenu,TEXT("Change")); return hMenu;}HMENU createPopMenu(HWND hwnd){ HMENU hMenu = CreateMenu(); HMENU hPop = CreateMenu(); AppendMenu(hPop,MF_STRING,IDM_POP_ONE,TEXT("One")); AppendMenu(hPop,MF_STRING,IDM_POP_TWO,TEXT("Twod")); AppendMenu(hMenu,MF_POPUP,(UINT_PTR)hPop,TEXT("Pop")); return hMenu;}HACCEL createAccelerator(HWND hwnd){ ACCEL acce[2]; acce[0].fVirt = FCONTROL | FNOINVERT | FVIRTKEY; acce[0].key = 'A'; acce[0].cmd = IDM_MENU_ADD; acce[1].fVirt = FCONTROL | FNOINVERT | FVIRTKEY; acce[1].key = 'R'; acce[1].cmd = IDM_MENU_REM; HACCEL hAccel = CreateAcceleratorTable(acce,2); return hAccel;}

你可能感兴趣的文章
python 模板中的语法
查看>>
JavaFX控件——FileChooser(文件选择框)
查看>>
视频直播网站开发千万不能忘的一个知识点
查看>>
Unity 3D中的射线与碰撞检测
查看>>
3月21日云栖精选夜读 | 重磅发布:阿里开源 OpenJDK 长期支持版本 Alibaba Dragonwell ...
查看>>
puppet确保程序运行
查看>>
Java spring boot 2.0连接mysql异常:The server time zone value 'Öйú±ê×¼Ê...
查看>>
Python爬虫入门教程 7-100 蜂鸟网图片爬取之二
查看>>
使用expo在安卓模拟器中运行React Native程序
查看>>
码农西游 | 写一本技术书可以赚多少钱
查看>>
最详细的Vue Hello World应用开发步骤
查看>>
标签打印软件如何制作三角形合格证
查看>>
阿里云Web应用防火墙知识,了解阿里云Web应用防火墙
查看>>
通过iotop与performance_schema.threads查看mysql的IO使用情况
查看>>
struts
查看>>
Spring Cloud服务短路Netflix Hystrix
查看>>
mysql5.7 修改默认密码
查看>>
把.Net开发环境迁移到Linux上去
查看>>
Android BottomNavigationBar底部导航控制器的使用
查看>>
Kubernetes Dashboard on Ubuntu 16.04安装记录
查看>>