Options (checkBoxes at the bottom of the Editor), are optional. Available options are as follows:
The
next step after you are finished with the menu resource script is to reference
it in your program.
You
can do this in two different places in your program.
[M00_Menu 1000
M00_Say_Hello 1001
M00_Say_GoodBye 1002
M00_Exit 1003
M00_Test 1004]
[hMenu: 0]
Main:
call 'Kernel32.GetModuleHandleA' &NULL
| mov D§hInstance eax
call 'User32.LoadIconA' 0 &IDI_WINLOGO
| mov D§wc_hIcon eax D§wc_hIconSm eax
call 'User32.LoadCursorA' 0 &IDC_ARROW
| mov D§wc_hCursor eax
call 'User32.RegisterClassExA' WindowClassEX
call 'User32.LoadMenuA' D§hInstance M00_Menu
mov D§hMenu eax
call 'User32.CreateWindowExA' &NULL ClassName
AppName,
&WS_OVERLAPPEDWINDOW,
&CW_USEDEFAULT &CW_USEDEFAULT &CW_USEDEFAULT &CW_USEDEFAULT,
&NULL D§hMenu D§hInstance &NULL
mov D§WindowHandle eax
call 'User32.ShowWindow' D§WindowHandle
&SW_SHOWNORMAL
call 'User32.UpdateWindow' D§WindowHandle
L1: call 'User32.GetMessageA' FirstMessage 0 0 0 | cmp eax 0 | je L9>
call 'User32.TranslateMessage'
FirstMessage
call 'User32.DispatchMessageA'
FirstMessage
jmp L1<
L9: call 'Kernel32.ExitProcess' 0
__________________________________________________________________________________
[Test_string: 'You selected Test menu item' 0
Hello_string: 'Hello, my friend' 0
Goodbye_string: 'See you again, bye' 0]
Proc MainWindowProc:
Arguments @Adressee, @Message, @wParam, @lParam
pushad
.If D@Message e &WM_DESTROY
call 'User32.PostQuitMessage' &NULL
.Else_If D@Message e &WM_COMMAND
mov eax D@wParam
If eax = M00_Test
call 'User32.MessageBoxA' &NULL Test_string AppName
&MB_OK
Else_If eax = M00_Say_Hello
call 'User32.MessageBoxA' &NULL Hello_string AppName &MB_OK
Else_If eax = M00_Say_GoodBye
call 'User32.MessageBoxA' &NULL Goodbye_string AppName
&MB_OK
Else
call 'User32.DestroyWindow' D@Adressee
End_If
.Else
popad
call 'User32.DefWindowProcA' D@Adressee D@Message D@wParam D@lParam
Exit
.End_If
popad | mov eax &FALSE
EndP
These
values MUST be those returned by the Menu Editor when you click on [Store
Equates to CliBoard].
.Else_If D@Message e &WM_COMMAND
mov eax D@wParam
If eax = M00_Test
call 'User32.MessageBoxA' &NULL Test_string AppName
&MB_OK
Else_If eax = M00_Say_Hello
call 'User32.MessageBoxA' &NULL Hello_string AppName &MB_OK
Else_If eax = M00_Say_GoodBye
call 'User32.MessageBoxA' &NULL Goodbye_string AppName
&MB_OK
Else
call 'User32.DestroyWindow' D@Adressee
End_If
In
the window procedure, we process WM_COMMAND messages. When the user selects
a menu item, the menu ID of that menu item is sended to the window procedure
in the low word of wParam along with the WM_COMMAND message. So when we
store the value of wParam in eax, we compare the value in ax to the menu
IDs we defined previously and act accordingly. In the first three cases,
when the user selects Test, Say Hello, and Say GoodBye menu items, we just
display a text string in a message box.
If
the user selects Exit menu item, we call DestroyWindow with the handle
of our window as its parameter which will close our window.
As
you can see, specifying menu ID in a window class is quite easy and straightforward.
However you can also use an alternate method to load a menu in your window.
I won't show the entire source code here. The resource file is the same
in both methods. There are some minor changes in the source file which
I 'll show below.
call 'USER32.LoadMenuA' D§hInstance 1000
mov D§hMenu eax
call 'USER32.CreateWindowExA' &NULL ClassName
AppName,
&WS_OVERLAPPEDWINDOW &CW_USEDEFAULT,
&CW_USEDEFAULT &CW_USEDEFAULT &CW_USEDEFAULT
&NULL D§hMenu,
D§hInstance &NULL
Before
calling CreateWindowEx, we call LoadMenu with the instance handle and a
pointer to the name of our menu. LoadMenu returns the handle of our menu
in the resource file which we pass to CreateWindowEx.