zoukankan      html  css  js  c++  java
  • windows编程之菜单操作

    分清几个概念

    <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<Windows.h>
    
    #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		301
    
    LRESULT 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;
    }



  • 相关阅读:
    physicslectureGriavity
    electromagnetic
    dp
    physicsmechanic wave
    C# 2.0 Specification(迭代器)(二)
    C#类、接口、虚方法和抽象方法接口与抽象类的区别实例
    web.config connectionStrings 数据库连接字符串的解释(转载)
    onpropertychange事件
    C#中ParameterizedThreadStart和ThreadStart区别
    C# 文件操作全收录
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5208000.html
Copyright © 2011-2022 走看看