Managing Lists

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.

Listing 10.3: A program working with two lists
image from book
 //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 
image from book
 

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).



The Assembly Programming Master Book
The Assembly Programming Master Book
ISBN: 8170088178
EAN: 2147483647
Year: 2004
Pages: 140
Authors: Vlad Pirogov

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net