-------------------------------------------------- ------------------------------ Related menus and accelerator key menu is the most important component of the Windows standard interface, the menu of the window The strip is located below the title bar, which is often referred to as the main menu, and the menu item below the main menu is called a drop-down menu, or the pop-up menu, submenu, etc., and click on the left side of the title bar. A menu will pop up, called the system menu. The accelerator is actually a shortcut key of the menu item, and the application often marks the shortcuts of the menu item on the right side of the menu item, which is the accelerator button. The structure of the menu is nested, that is, you can pop up another menu when you select a menu item. The type of menu item is normal, disabled, ash, horizontal separation line, etc. This section demonstrates various types of menus: You can see normal and disabled, gray menu in the main menu, you can use the right-click window to pop up a "pop-up menu", too I can see that I have added a few new content in the system menu. In programming processing, the menu is defined in the resource file (of course, you can use the resource file, and use the AppendMenu one item in the program, but use the resource file is undoubtedly the easiest way), then Use loadMenu to get the menu handle to use. The syntax of the menu in the resource file is as follows: Menu ID Menu DiscardableBeginPopup "Main menu item 1" BeginMenuItem "pop-up menu item one", command ID [, option] MenuItem "pop-up menu item 2", command ID [, option] MenuItem SeparatorNuItem "Pop-up Menu item 3", command id [, option] ... Endpopup "Main menu item 2" BeginMenuItem "pop-up menu item 1", command ID [Option] MenuItem "pop-up menu item 2", Command ID [, Option] MenuItem "pop-up menu item three", command id [, option] ... Popup "Nested menu item" BeginMenuItem "pop-up menu item", command id [, option] menuitem "pop-up Menu item 2 ", command ID [, option] menuItem" pop-up menu item three ", command ID [, option] ... Endend ... End menu ID is what we use to load menu in the program with loadMenu Resource number, MenuItem Separator defines the horizontal line with the separated menu item, the option in the menu item definition is attribute, such as grayed is ashing, INACTIVE is disabled.
The accelerator is actually defined corresponding to the hotkey corresponding to each menu item, the definition method is as follows: Accelerator ID acceleratorsbeginvk_f1, the corresponding menu command ID, Virtkeyvk_f2, the corresponding menu command ID, Virtkey ... "a", corresponding Menu Command ID, Virtkey, Control "B", the corresponding menu command id, Virtkey, Controlend where the accelerator key ID is our resource number we loaded with the loadAclerator in the program, and each item below defines a key. VK_F1 represents the use of F1, "a" to indicate the key A, the following Virtkey is required, then the control "or shift, alt" indicates the combination of CONTROL keys, that is, if you define: "c", idm_copy, Virtkey, Control and define menuItem "copy" in the menu definition, IDM_COPY, then pressing Ctrl-C in the program, actually executing the menu item "copy". The programming of the menu and accelerator is very simple. Initialization, you need to do the following: Make the program's instance handle (hinstance) to load the menu, get the menu handle with the loadaccelerator to load the accelerator button, get the accelerator key handle registration window Class Create a window When you create a menu handle display window, then enter the message loop, with TranslateAccelerator with translateAccelerator (see the source program) When the window is displayed, when a menu item or a accelerator button is pressed When Windows sends a WM_COMMAND message to the window process, when the menu item in a system menu is pressed, Windows sends WM_SYSCOMMAND to the window process, the ID of the menu item is included in the low 16 bits of WPARAM, in general Programming, if we do not process the system menu message, just create a section in the process of the WM_COMMAND message. The statement of each menu command ID is processed.
Source programs using menus and acceleration keys .386.Model flat, stdcalloption caseMap: None; Case Sensitive; >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>> include windows.incinclude user32.incinclude kernel32.incinclude comctl32.incinclude comdlg32.incinclude shell32.incinclude gdi32.incincludelib user32.libincludelib kernel32.libincludelib comctl32.libincludelib comdlg32.libincludelib shell32.libincludelib gdi32 .lib; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> IDI_MAIN equ 1000; iconIDA_MAIN equ 2000 ;
AcceleratorIDM_MAIN equ 4000IDM_OPEN equ 4101IDM_OPTION equ 4102IDM_EXIT equ 4103IDM_SETFONT equ 4201IDM_SETCOLOR equ 4202IDM_FIND equ 4203IDM_FINDPREV equ 4204IDM_FINDNEXT equ 4205IDM_TOOLBAR equ 4206IDM_TOOLBARTEXT equ 4207IDM_INPUTBAR equ 4208IDM_STATUSBAR equ 4209IDM_HELP equ 4301IDM_ABOUT equ 4302; >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Data segments; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Fold. *********************************************************** *********** ********; flag bit definition f_toolbar EQU 00000001BF_TOOLBARTEXT EQU 00000010BF_INPUTBAR EQU 0000100BF_STATUSBAR EQU 00001000B; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >; Data segment; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> DatazclassName DB "Menu Example", 0SzcaptionMain DB '
Menu Application Example ', 0SzMenuhelp DB "Help Topics (& H)", 0Sz GeneNuabout DB "About this Program (& A) ...", 0; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Code segment; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folding;> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> START: Call_winmaininvoke exitprocess, NULL; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> _ WinMain proclocal @stWcMain: WNDCLASSEXlocal @stMsg: MSGlocal @hAcceleratorinvoke InitCommonControlsinvoke GetModuleHandle, NULLmov hInstance, eaxinvoke LoadIcon, hInstance, IDI_MAINmov hIcon, eaxinvoke LoadMenu, hInstance, IDM_MAINmov hMenu, Eax; ************** Register window *************************************** *********** invoke LoadCursor, 0, IDC_ARROWmov @ stWcMain.hCursor, eaxmov @ stWcMain.cbSize, sizeof WNDCLASSEXmov @ stWcMain.hIconSm, 0mov @ stWcMain.style, CS_HREDRAW or CS_VREDRAWmov @ stWcMain.lpfnWndProc, offset WndMainProcmov @ stWcMain.cbClsExtra, 0mov @ stWcMain.cbWndExtra, 0mov eax, hInstancemov @ stWcMain.hInstance, eaxmov @ stWcMain.hIcon, 0mov @ stWcMain.hbrBackground, COLOR_WINDOW 1mov @ stWcMain.lpszClassName, offset szClassNamemov @ stWcMain.lpszMenuName, 0invoke RegisterClassEx , addr @stwcmain; **************************************************************************************************************************************************************************************************************************** *********** Invoke CreateWindowEx, WS_EX_ClientedGe, / Offset SzclassName, Offset Szcaptionmain, / WS_OVERLAPPEDWINDOW OR WS_VSCROLL OR WS_HSCROLL, / 100, 100, 550, 300 , Null, Hmenu, Hinstance, Nullinvoke Showwindow, Hwinmain, SW_Shownormalinvoke UpdateWindow, HwinMain; ********************************************** *************************** Invoke LoadAccelerators, Hinstance, IDA_MAINMOV @ Haccelerator, Eax.While Trueinvoke GetMessage, Addr @ Stmsg, NULL, 0 , 0.break .if eax == 0invoke TranslateAccelerator, hWinMain, @ hAccelerator, addr @ stMsg.if eax == 0invoke TranslateMessage, addr @stMsginvoke DispatchMessage, addr @ stMsg.endif.endwret_WinMain endp; >>>>>>>> >>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WyMAINPROC PROC USES EBX EDI ESI, / HWND: DWORD, UMSG: DWORD , WParam: DWORD, LPARAM: DWordLocal @stpos: PointMov Eax, Umsg.if Eax == WM_CREATEMOV EAX, HWNDMOV HWINMAIN, EAXCALL _INIT; ******************* *****************************************************************. Elseif EAX == WM_COMMAND.if lParam == 0mov eax, wParammovzx eax, ax.if eax == IDM_EXITcall _Quit.elseif eax == IDM_TOOLBARxor dwFlag, F_TOOLBARcall _MenuStatus.elseif eax == IDM_TOOLBARTEXTxor dwFlag, F_TOOLBARTEXTcall _MenuStatus.elseif eax == IDM_INPUTBARxor dwFlag, F_INPUTBARCALL _MENUSTATUS.ELSEIF EAX == IDM_STATUSBARXOR DWFLAG, F_STATUSBARCALL _MENUSTATUSTUS.ELSE_DEBUG "Menu Command", "Command ID", EAX.Endif.Endif; **************************** ********************************************************************************* eax == WM_SYSCOMMANDmov eax, wParammovzx eax, ax.if eax == IDM_HELP || eax == IDM_ABOUT_Debug "menu command", "command ID", eax.elseinvoke DefWindowProc, hWnd, uMsg, wParam, lParamret.endif; *** *********************************************************** **************; Press the right button to pop up a POP Up menu; ************************************************************** *********************. Elseif EAX == WM_RBUTTONDOWNVOKE GETCURSORPOS, AddR @stposinvoke TRACKPOPUPMENU, HSUBMENU, TPM_LEFTALIGN, @ stpos.x, @ stpos.y, null, HWnd, NULL; ************************************************************************************************************************************************************************************************************************************************************************************** *************. Elseif Eax == WM_Closecall_Quit; ******************** **************************************************************************************. ElseInvoke DefWindowProc, HWND, UMSG, WPARAM, LPARAMRET.ENDIF;
*********************************************************** **********; Note: After WndProc processes the Windows message, you must return 0 in EAX; but the return value after the DEFWINDOWPROC cannot be changed, otherwise the window will not display!;*********************************************** ********************* * XOR EAX, EaxRetWndMainProc Endp; >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Folder Program; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>, hwwmall, hic; *************** *********************************************************** **; Popup menu to use the submenu to be implemented; ******************************************** ****************************** Invoke GetSubmenu, HMENU, 1MOV HSUBMENU, EAXCALL _MENUSTATUS; ******* *********************************************************** **********; Add a menu item in the system menu; **************************************** ********************************************** Invoke GetSystemMenu, HwinMain, Falsemov @ hsysmenu, EaxInvoke Appendmenu, @ HSYSMENU, MF_SEPARATOR, 0, NULLINVOKE APPENU, @ hsysmenu, mf_string, idm_help, offset sz Menuhelpinvoke appendmenu, @ hsysmenu, mf_string, idm_about, offset szmenuaboutret_init Endp; ******************************************************** ***********************; Set the status of the corresponding menu item according to the flag bit;
*********************************************************** ****************** _ MenuStatus proctest dwFlag, F_INPUTBAR.if ZERO? invoke CheckMenuItem, hMenu, IDM_INPUTBAR, MF_UNCHECKED.elseinvoke CheckMenuItem, hMenu, IDM_INPUTBAR, MF_CHECKED.endiftest dwFlag, F_TOOLBAR. if ZERO? invoke CheckMenuItem, hMenu, IDM_TOOLBAR, MF_UNCHECKED.elseinvoke CheckMenuItem, hMenu, IDM_TOOLBAR, MF_CHECKED.endiftest dwFlag, F_TOOLBARTEXT.if ZERO? invoke CheckMenuItem, hMenu, IDM_TOOLBARTEXT, MF_UNCHECKED.elseinvoke CheckMenuItem, hMenu, IDM_TOOLBARTEXT, MF_CHECKED.endiftest dwFlag, F_STATUSBAR.if ZERO invoke CheckMenuItem, hMenu, IDM_STATUSBAR, MF_UNCHECKED.elseinvoke CheckMenuItem, hMenu, IDM_STATUSBAR, MF_CHECKED.endifret_MenuStatus endp;? ************************ ******************************************************* _ Quit Procinvoke DestroyWindow, HwinMainInvoke PostquitMessage Nullret_quit endp; ************************************************************* *********************** * End Start program analyzes let us simply analyze this program, first of all this program and the simplest window program in the previous section. The difference is the message cycle, as follows: .While Trueinvoke GetMessage, Add r @ stMsg, NULL, 0,0.break .if eax == 0invoke TranslateAccelerator, hWinMain, @ hAccelerator, addr @ stMsg.if eax == 0invoke TranslateMessage, addr @stMsginvoke DispatchMessage, addr @ stMsg.endif.endw in circulation TranslateAccelerator is used to determine whether the message stored in the MSG structure is a keyboard message. If so, it looks for the accelerator key table corresponding to the handle @haccelerator. If a match is found, then it will send a WM_COMMAND message with the command ID, At the same time, it returns a non-0 value. At this time, the message has been processed, no need to call the following translateMessage and DispatchMessage, if not, then it will return 0, the message loop continues.