| ||
Until now, you worked with modal dialogs. The main property of such dialogs is that when they are called the program must wait until such a window is closed. However, after calling such windows , the program would continue execution. A modeless window allows the user to switch to other windows . Modeless dialogs are characterized by the following properties:
Modeless dialogs are created using the Createdialog function.
Modeless dialogs are destroyed by the DestroyWindow function.
For a modeless dialog to appear on the screen, it must have the WS_VISIBLE property, or the dialog creation command must be followed by the ShowWindow function.
Listing 9.4 illustrates a program that demonstrates a modeless dialog with a menu and ensures the processing of the accelerator messages.
// The MENU1.RC file // Definitions of constants #define WS_SYSMENU 0x00080000L #define WS_MINIMIZEBOX 0x00020000L #define WS_MAXIMIZEB0X 0x000l0000L #define WS_POPUP 0x80000000L #define VK_F5 0x74 #define st WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX MENUP MENU PCPUP "&First item" { MENUITEM "&First", 1 MENUITEM "S&econd", 2, HELP MENUITEM "What?", 8 } POPUP "& Second item" { MENUITEM "Thi&rd", 3 MENUITEM "Fo&urth", 4 MENUITEM SEPARATOR POPUP "Another subme&nu" { MENUITEM "Tenth ite&m", 6 } } MENUITEM "E&xit", 5 } // Identifiers #define IDI_ICON1 100 // Defining an icon IDI_ICON1 ICON "ico1.ico". // Defining the dialog DIAL1 DIALOG'0, 0, 240, 120 STYLE WS_POPUP St CAPTION "An example of modeless dialog" FONT 8, "Arial" { { MENUP ACCELERATORS { VK_F5, 4, VIRTKEY, ALT } ; The MENU1.INC file ; Constants ; The message arrives when the window is closed WM_CLOSE equ 10h WM_INITDIALOG equ 110h WM_SETICON equ 80h WM_COMMAND equ 111h ; Prototypes of external procedures EXTERN ShowWindow@8:NEAR EXTERN MessageBoxA@16:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN LoadIconA@8:NEAR EXTERN LoadMenuA@8:NEAR EXTERN SendMessageA@16:NEAR EXTERN SetMenu@8:NEAR EXTERN LoadAcceleratorsA@8:NEAR EXTERN TranslateAcceleratorA@12:NEAR EXTERN GetMessageA@16:NEAR EXTERN DispatchMessageA@4:NEAR EXTERN PostQuitMessage@4:NEAR EXTERN CreateDialogPararaA@20:NEAR EXTERN DestroyWindow@4:NEAR EXTERN TranslateMessage@4:NEAR ; Structures ; Message structure MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS ; The MENU1.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall include menu1.inc ; INCLUDELIB directives for the linker includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ; Data segment _DATA SEGMENT NEWHWND DD 0 MSG MSGSTRUCT <?> HINST DD 0 ; Application descriptor PA DB "DIAL1", 0 PMENU DB "MENUP", 0 STR1 DB "Exit the program", 0 STR2 DB "Message", 0 STR3 DB "Fourth item selected", 0 ACC DWORD ? _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application descriptor PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX ; Load the accelerators PUSH OFFSET PMENU PUSH [HINST] CALL LoadAcceleratorsA@8 MOV ACC, EAX ; Store the table descriptor ; Create the modeless dialog PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL CreateDialogParamA@20 ; Show the modeless dialog MOV NEWHWND, EAX PUSH 1 ; SW_SHOWNORMAL PUSH [NEWHWND] CALL ShowWindow@8 ; Show the newly created window ; Message-processing loop MSG_LOOP: PUSH 0 PUSH 0 PUSH 0 PUSH OFFSET MSG CALL GetMessageA@16 CMP EAX, 0 JE END_LOOP ; Translate the accelerator message PUSH OFFSET MSG PUSH [ACC] PUSH [NEWHWND] CALL TranslateAcceleratorA@12 CMP EAX, 0 JNE MSG_LOOP PUSH OFFSET MSG CALL TranslateMessage@4 PUSH OFFSET MSG CALL DispatchMessageA@4 JMP MSG_LOOP END_LOOP: PUSH 0 CALL ExitProcess@4 ; Window procedure ; Position of parameters in the stack ; [EBP+014H] LPARAM ; [EBP+10H] WAPARAM ; [EBP+0CH] MES ; [EBP+8] HWND WNDPROC PROC PUSH EBP MOV EBP, ESP PUSH EBX PUSH ESI PUSH EDI ;---------------- CMP DWORD PTR [EBP+0CH], WM_CLOSE JNE L1 ; Close the dialog JMP L5 L1: CMP DWORD PTR [EBP+0CH], WM_INITDIALOG JNE L3 ; Load the icon PUSH 100 ; Icon identifier PUSH [HINST] ; Process identifier CALL LoadIconA@8 ; Set the icon; PUSH EAX PUSH 0 ; Icon type (small) PUSH WM_SETICON PUSH DWORD PTR [EBP+08H] CALL SendMessageA@16 ; Load the menu PUSH OFFSET PMENU PUSH [HINST] CALL LoadMenuA@8 ; Set the menu PUSH EAX PUSH DWORD PTR [EBP+08H] CALL SetMenu@8 ;------------------- MOV EAX, 1 ; Return a nonzero value JMP FIN ; Checking whether or not something happened ; to the dialog controls L3: CMP DWORD PTR [EBP+0CH], WM_COMMAND JE L6 JMP FINISH ; Defining identifier ; In this case, this is the menu item identifier L6: CMP WORD PTR [EBP+10H], 4 JNE L4 PUSH 0 ; MB_OK PUSH OFFSET STR2 PUSH OFFSET STR3 PUSH 0 CALL MessageBoxA@16 JMP FINISH L4: CMP WORD PTR [EBP+10H], 5 JNE FINISH ; Message PUSH 0 ; MB_OK PUSH OFFSET STR2 PUSH OFFSET STR1 PUSH 0 CALL MessageBoxA@16 ; Close the modeless dialog L5: PUSH DWORD PTR [EBP+08H] CALL DestroyWindow@4 ; Send the message to exit ; the message-processing loop PUSH 0 CALL PostQuitMessage@4 ; The WM_QUIT message FINISH: MOV EAX, 0 FIN: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START
Some comments are needed to explain the program provided in Listing 9.4.
A modeless dialog is specified in the resource file just as modal one would be specified. Because I didn't specify the WS_VISIBLE property when describing window properties, to make the dialog visible, it is necessary to use the ShowWindow function.
To exit the program in this case, it is necessary not only to remove the dialog from memory using the DestroyWindow function but also to exit the message-processing loop. The latter is achieved by calling the PostQuitMessage function.
To conclude, it is necessary to mention that I didn't cover the following types of resources:
The resource containing unstructured data
name RCDATA BEGIN raw-data ... END
The VERSIONINFO resource
ID VERSIONINFO BEGIN block-statement ... END
Both of these resources are rarely used in comparison to other types of resources. Therefore, I won't concentrate your attention on them.
| ||