Eighth lesson menu
In this lesson, we will join a menu in our app.
Theory: The menu can be said to be one of the most important elements of Windows. With it, the user can easily select an operation command. Users can read all the menu items to clear the probably functionality provided by the application, and can be handled immediately, no need to read the manual. Because the menu gives the user The convenient way, so you have to comply with the general standards when you join the menu. For example: the first two menu items are "file" and "edit", and finally "Help", you can insert it in this You want to define the menu item. If the running menu command pops up a dialog box, then add the omit (...) after the menu item. The menu is a resource. There is a resource in addition to the menu. Box, string, icon, bitmap resource, etc. In the link, the link will add the resource to the executable, and finally in our executable includes both the machine instruction and resources. You can edit in any text The script file is written in the server, you can specify the appearance of the resource presentation and other properties. Of course, the more intuitive way is to use the resource editor, usually the resource editor is packaged in the compilation environment, like Visual C , Borland C and the like have a resource editor. We can define a menu resource as follows:
Mymenu Menu
{
[Menu List Here]
}
This is very similar to the definition of structures in the C language. MyMenu is similar to the defined variable, while Menu is similar to keywords. Of course, you can use another way, that is, use Begin and End instead of the curly bracket, which is the same as the style in the Pascal language.
In the list of menu items is a big string of MenuItem and POPUP statements. MenuItem defines a menu item that does not activate the dialog after the selection is selected. Its syntax is as follows:
Menuitem "& Text", ID [Options]
It is started by the keyword menuitem, followed by Menuitem, refers to the name string of the menu item, the first character after the symbol "&" will take the down line, which is also the shortcut key of the menu item. The role of the ID When the menu is selected, Windows's message processing process is used to distinguish menu items. There is no doubt that the ID number must be unique. Options have the following available properties:
Grayed represents the menu item inactive, that is, the WM_COMMAND message is not generated when it is selected. This menu is displayed in gray. Inactive represents the menu item inactive, that is, the WM_COMMAND message is not generated when it is selected. This menu is displayed in normal colors. Menubreak This menu item and the subsequent menu item are displayed in the norm. (Translator Note: It is more difficult to describe, please do an experiment.) Help This menu item is aligned with the subsequent menu item. (Translator Note: I compile the menu item with this flag under Windows2000, which seems to have not played) You can use the above flags alone, or you can use them or together. Of course, INACTIVE and GRAYED cannot be used at the same time. The grammar of POPUP is as follows:
Popup "& Text" [, Options]
{
[Menu List]
}
Popup defines a menu item When the menu item is selected, a submenu will pop up. There is another special type of MenuiteM statement MenuItem Separator, which represents a separation line in the menu item location. After defining the menu, you can use the menu resources defined in the script in the program. You can use them in two places (or in two ways):
A member of the WNDCLASSEX structure in Lpsz GeneNuname. For example, you have a menu "firstmenu", you can contact it to your window as follows:
.DATA
Menuname DB "firstmenu", 0 .........................
.........................
.Code
.........................
MOV wc.lpsz Gene, Offset Menuname
.........................
In the CREATEWINDOWEX function, indicate the handle of the menu:
.DATA
Menuname DB "Firstmenu", 0
HMENU HMENU?
.........................
.........................
.Code
.........................
Invoke Loadmenu, Hinst, Offset Menuname
Mov Hmenu, EAX
Invoke CreateWindowex, Null, Offset CLSName, /
Offset Caption, WS_OVERLAPPEDWINDOW, /
CW_USEDEFAULT, CW_USEDEFAULT, /
CW_USEDEFAULT, CW_USEDEFAULT, /
NULL, /
Hmenu, /
Hinst, /
NULL /
.........................
You may ask, what is the difference between these two? When you use the first method, since it is specified in the window class, all the windows derived by the window class will have the same menu. If you want to have different menus from the window from the same class, use the second middle method, which "overrides the" The menu specified in the WNDCLASSEX structure through the menu specified by the function CreateWindowex. Next, let's see how it will notify the Windows window process when the user chooses a menu item: When the user selects a menu item, the Windows window process will receive a WM_COMMAND message, the bottom byte of the passing parameter wPARAM Contains the ID number of the menu item. Ok, the above is everything about menu items, let's practice below.
Example: The first example shows the first method of specifying a menu item:
.386 .Model flat, Stdcall Option Casemap: NONE
Winmain Proto: DWORD,: DWORD,: DWORD,: DWORD
Include /masm32/include/windows.inc include /masm32/include/user32.inc include /masm32/include/kernel32.inc includelib /masm32/lib/user32.lib incrudelib /masm32/lib/kernel32.lib
.data ClassName db "SimpleWinClass", 0 AppName db "Our First Window", 0 MenuName db "FirstMenu", 0;. The name of our menu in the resource file Test_string db "You selected Test menu item", 0 Hello_string db " Hello, My Friend ", 0 goodbye_string db" see you again, bye ", 0
.DATA? Hinstance Hinstance? Commandline LPSTR?
.const IDM_TEST equ 1; Menu IDs IDM_HELLO equ 2 IDM_GOODBYE equ 3 IDM_EXIT equ 4.code start: invoke GetModuleHandle, NULL mov hInstance, eax invoke GetCommandLine mov CommandLine, eax invoke WinMain, hInstance, NULL, CommandLine, SW_SHOWDEFAULT invoke ExitProcess, eax
WinMain proc hInst: HINSTANCE, hPrevInst: HINSTANCE, CmdLine: LPSTR, CmdShow: DWORD LOCAL wc: WNDCLASSEX LOCAL msg: MSG LOCAL hwnd: HWND mov wc.cbSize, SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra, NULL mov wc.cbWndExtra, NULL push hInst pop wc.hInstance mov wc.hbrBackground, COLOR_WINDOW 1 mov wc.lpszMenuName, OFFSET MenuName; Put our menu name here mov wc.lpszClassName, OFFSET ClassName invoke LoadIcon, NULL, IDI_APPLICATION mov wc.hIcon, eax mov wc.hIconSm, eax invoke LoadCursor, NULL, IDC_ARROW mov wc.hCursor, eax invoke RegisterClassEx, addr wc invoke CreateWindowEx, NULL, aDDR ClassName, aDDR AppName, / WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, / CW_USEDEFAULT , CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, / HINST, NULL MOV HWND, EAX INVOKE ShowWindow, Hwnd, SW_SHOWNORMAL INVOKE UPDATEWINDOW, HWND .WH Ile True Invoke GetMessage, Addr MSG, NULL, 0, 0.Break .if (! EAX) Invoke DispatchMessage, Addr Msg .Endw Mov EAX, Msg.wParam Ret Winmain Endp
WndProc proc hWnd: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM .IF uMsg == WM_DESTROY invoke PostQuitMessage, NULL .ELSEIF uMsg == WM_COMMAND mov eax, wParam .IF ax == IDM_TEST invoke MessageBox, NULL, ADDR Test_string , OFFSET AppName, MB_OK .ELSEIF ax == IDM_HELLO invoke MessageBox, NULL, ADDR Hello_string, OFFSET AppName, MB_OK .ELSEIF ax == IDM_GOODBYE invoke MessageBox, NULL, ADDR Goodbye_string, OFFSET AppName, MB_OK .ELSE invoke DestroyWindow, hWnd .ENDIF. Else Invoke DefWindowProc, HWND, UMSG, WPARAM, LPARAM RET .Endif xor EAX, EAX RET WNDPROC ENDP End Start ************************************ *********************************************************** **************************************************** MENU.RC
*********************************************************** *********************************************************** *********************
#define idm_test 1 #define idm_hello 2 #define idm_goodbye 3 #define idm_exit 4
FirstMenu Menu {Menuitem "& Say Hello", IDM_Hello Menuitem "Say & Goodbye", IDM_GOODBYE MENUITEM SEPARATOR MENUITEM "E & XIT", IDM_EXIT} MenuItem "& Test", IDM_Test}
Analysis: Let's analyze the resource file first:
#define idm_test 1 / * equal to idm_test EQU 1 * /
#define idm_hello 2
#define IDM_GODBYE 3
#define idm_exit 4
The above line defines the ID number of the menu item. As long as the menu item ID number must be unique, you can give any value for the ID number.
FirstMenu Menu
Use the Keyword Menu to define the menu.
Popup "& Popup" {MENUITEM "& SAY HELLO", IDM_HELLO MENUITEM "SAY & Goodbye", IDM_GODBYE MENUITEM SEPARATOR MENUITEM "E & XIT", IDM_EXIT} Defines a submenu with four menu items, where the third menu item is a divider.
Menuitem "& Test", IDM_Test
Define one of the main menu. Let's take a look at the source code.
Menuname DB "firstmenu", 0; the name of our menu in the resource file.
Test_String DB "You SELECTED TEST MENU ITEM", 0
Hello_String DB "Hello, My Friend", 0
Goodbye_string db "see you again, bye", 0
Menuname is the name of the menu specified in the resource file. Because you can define any multiple menus in the script file, you must specify that one you want to use before use, the next line is displayed in the string in the relevant dialog box when selecting the menu item.
IDM_TEST EQU 1; Menu IDS
IDM_HELLO EQU 2
IDM_GOODBYE EQU 3
IDM_EXIT EQU 4
Define the menu item ID number during the Windows window. These values must be the same as those in the script file.
.ELSEIF uMsg == WM_COMMAND mov eax, wParam .IF ax == IDM_TEST invoke MessageBox, NULL, ADDR Test_string, OFFSET AppName, MB_OK .ELSEIF ax == IDM_HELLO invoke MessageBox, NULL, ADDR Hello_string, OFFSET AppName, MB_OK .ELSEIF ax = = IDM_GODBYE INVOKE MessageBox, Null, Addr Goodbye_String, Offset Appname, MB_OK .ELSE INVOKE DESTROYWINDOW, HWND .Endif
We handle the WM_COMMAND message during this window. When a user selects a menu item, the ID item of the menu item is sent to the Windows window process in the WPARAM, and we save it to the EAX register to compare with a predefined menu item ID. In the first three cases, when we select Test, Say Hello, Say Goodbye menu item, a dialog box is popped up with a related string, when we select the exit menu item, we call the function DestroyWindow, where the parameters are our The handle of the window is destroyed. As you can see, by specifying a menu name in a window class to generate a menu for an application to simply and intuitive. In addition to this method, you can use another method, where the resource file is the same, and there is only a few changes in the source file. These changes are as follows:
.DATA?
Hinstance Hinstance?
COMMANDLINE LPSTR?
HMENU HMENU?; Handle Of Our Menu defines a variable to save the handle of our menu, then:
invoke LoadMenu, hInst, OFFSET MenuName mov hMenu, eax INVOKE CreateWindowEx, NULL, ADDR ClassName, ADDR AppName, / WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, / CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hMenu, / hInst, NULL
Call the LoadMenu function, the function needs an instance handle and the menu name of the string, the result returns the handle pointing to the menu, and then transmits the menu handle that CreateWindowEx just returned.