| ||
This section considers the processing of a dialog with two lists. The right list is filled by double-clicking elements from the first list. Alternatively, to move an item from the left list to the right list, press the <Insert> key. You must also take into account the possibility that a user will double-click the same element twice. Principally, there is nothing difficult here. The comments to this situation will be provided after Listing 10.3. However, I'd like to explain one important element, the list, and draw your attention to some important aspects of working with it.
//The DIALLST.RC file //Constant definitions #define WS_SYSMENU 0x00080000L #define WS_MINIMIZEBOX 0x00020000L #define WS_MAXIMIZEBOX 0x000l0000L #define WS_VISIBLE 0x10000000L #define WS_TABSTOP 0x000l0000L #define WS__VSCROLL 0x00200000L #define WS_THICKFRAME 0x00040000L #define LBS_NOTIFY 0x000lL #define LBS_SORT 0x0002L #define LBS_WANTKEYBOARDINPUT 0x0400L // Identifiers #define LIST1 101 #define LIST2 102 #define IDI_ICON13 // Define an icon IDI_ICON1 ICON "ico1.ico" // Dialog definition DIAL1 DIALOG 0, 0, 210, 110 STYLE WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX CAPTION "First dialog box example" FONT 8, "Arial" { CONTROL "ListBox1", LIST1, "listbox", WS_VISIBLE WS_TABSTOP WS_VSCROLL WS_THICKFRAME LBS_NOTIFYLBS_WANTKEYBOARDINPUT, 16, 16, 70, 75 CONTROL "ListBox2", LIST2, "listbox", WS_VISIBLE WS_TABSTOP WS_VSCROLL WS_THICKFRAME LBS_NOTIFY LBS_SORT, 116, 16, 70, 75 } ; The DIALLST.INC file ; Constants ; The message arrives when the window is closed WM_CLOSE equ l0h WM_INITDIALOG equ 110h WM_SETICON equ 80h WM_COMMAND equ 111h WM_VKEYTOITEM equ 2Eh LB_ADDSTRING equ 180h LBN_DBLCLK equ 2 LB_GETCURSEL equ 188h LB_GETTEXT equ 189h LB_FINDSTRING equ 18Fh VK_INSERT equ 2Dh ; Prototypes of external procedures EXTERN ExitProcess@4:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN DialogBoxParamA@20:NEAR EXTERN EndDialog@8:NEAR EXTERN LoadIconA@8:NEAR EXTERN SendMessageA@16:NEAR EXTERN SendDlgItemMessageA@20:NEAR EXTERN MessageBoxA@16:NEAR ; Structures ; Message structure MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS ; The DIALLST.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall include diallst.inc ; INCLUDELIB directives for the linker to link libraries includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ;---------------------------------------- ; Data segment _DATA SEGMENT MSG MSGSTRUCT <?> HINST DD 0 ; Application descriptor PA DB "DIAL1", 0 BUFER DB 100 DUP(0) STR1 DB "First", 0 STR2 DB "Second", 0 STR3 DB "Third", 0 STR4 DB "Fourth", 0 STR5 DB "Fifth", 0 STR6 DB "Sixth", 0 STR7 DB "Seventh", 0 STR8 DB "Eighth", 0 STR9 DB "Nineth", 0 STR10 DB "Tenth", 0 STR11 DB "Eleventh", 0 STR12 DB "Twelveth", 0 STR13 DB "Thirteenth", 0 STR14 DB "Fouteenth", 0 STR15 DB "Fifteenth", 0 INDEX DD OFFSET STR1 DD OFFSET STR2 DD OFFSET STR3 DD OFFSET STR4 DD OFFSET STR5 DD OFFSET STR6 DD OFFSET STR7 DD OFFSET STR8 DD OFFSET STR9 DD OFFSET STR10 DD OFFSET STR11 DD OFFSET STR12 DD OFFSET STR13 DD OFFSET STR14 DD OFFSET STR15 _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application descriptor PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX ;--------------------------- PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL DialogBoxParamA@20 CMP EAX, -1 JNE KOL ; Error message KOL: ;---------------------------------- 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 PUSH 0 PUSH DWORD PTR [EBP+08H] CALL EndDialog@8 JMP FINISH L1: CMP DWORD PTR [EBP+0CH], WM_INITDIALOG JNE L2 ; Load the icon PUSH 3 ; 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 ; Fill the left list MOV ECX, 15 MOV ESI, 0 LO1: PUSH ECX ; Save the loop variable PUSH INDEX[ESI] PUSH 0 PUSH LB_ADDSTRING PUSH 101 PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA@20 ADD ESI, 4 POP ECX LOOP LO1 JMP FINISH L2: CMP DWORD PTR [EBP+0CH], WM_COMMAND JNE L3 ; Is there a message from the left list? CMP WORD PTR [EBP+10H], 101 JNE FINISH ; Wasn't there a double-click event? CMP WORD PTR [EBP+12H], LBN_DBLCLK JNE FINISH ; There was a double-click; now, determine on which item ; Get the index of the chosen item L4: PUSH 0 PUSH 0 PUSH LB_GETCURSEL PUSH 101 PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA@20 ; Copy the list item into the buffer PUSH OFFSET BUFER PUSH EAX ; Record index PUSH LB_GETTEXT PUSH 101 PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA@20 ; Determine whether this element is in the right list PUSH OFFSET BUFER PUSH -1 ; Search the entire list PUSH LB_FINDSTRING PUSH 102 PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA@20 CMP EAX, -1 JNE FINISH ; The element was found ; If the item was not found, it can be added PUSH OFFSET BUFER PUSH 0 PUSH LB_ADDSTRING PUSH 102 PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA@20 MOV EAX, -1 JMP FIN L3: ; Check whether a key has been pressed CMP DWORD PTR [EBP+0CH], WM_VKEYTOITEM JNE FINISH CMP WORD PTR [EBP+10H], VK_INSERT JE L4 MOV EAX, -1 JMP FIN FINISH: MOV EAX, 0 FIN: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START
The means for managing lists can be classified into two groupsmessages and properties. [i] The properties are specified in the resource file. For example, setting the LBS_SORT property automatically sorts the list contents any time a new element is added to the list. One of the most important properties is LBS_WANTKEYBOARDINPUT . If this property is set, the application receives the WM_VKEYTOITEM message when the user presses any key, provided that this list is activated. You can choose either independent processing (the <Page Up> key) or standard processing. If standard processing is not needed, the dialog function must return a negative value.
The program in Listing 10.3 requires some comments.
First, pay attention to the SendDlgItemMessage function. This function is more convenient for sending messages to elements of a dialog box than the SendMessage function, because the item in it is identified by the number specified in the resource file instead of a descriptor, which it is necessary to determine beforehand.
Have a look at the resource file, and you'll see that the right list is assigned the LBS_SORT property. If this property is assigned to the list, then this list remains ordered after an element is added to it using the LB_ADDSTRING message. The LBS_SORT property costs significant overhead for the Windows operating system. By sending the WM_COMPAREITEM message, the operating system determines the required position for the new list item and then inserts the new item by sending the LB_INSERTSTRING message.
It is also necessary to draw your attention to the loop that fills the left list. You must store the ECX register in the stack. Well, isn't it quite natural when organizing a loop using the loop command? I would oppose this statement and declare that this isn't obvious. Unfortunately, available documentation on API functions and Windows messages doesn't state which processor registers are saved and which aren't saved for a specific API function. All this information has to be discovered experimentally. The only known fact is that the EBX, EBP, EDI, and ESI registers must not change. The WM_VKEYTOITEM message arrives when the user presses any key if that the list is activated. For this feature to work, the list must be assigned the LBS_WANTKEYBOARDINPUT property. Because this property is set only for the left list, you don't need to check from which list the message arrived.
[i] The same is true for all elements in a dialog box. Don't you think that this is similar to objects in properties in object-oriented programming? However, if you dive deeper, you'll discover that a considerable part of the properties will once again be reduced to message processing (see comments about the program presented in Listing 10.3).
| ||