The Assembly Programming Master Book
| ||
| ||
|
Child Windows and Owned Windows
Later, you will see many times that windows have numerous attributes. In addition, windows can be related to each other in a certain way. In other words, every window can have a parent window and several child windows. A window that has no parent is called a top-level window. All examples considered previously demonstrated top-level windows. Elements located in the window ( buttons , lists, etc.) are child windows. In addition to child windows, there are owned windows. An owned window has an owner but is not a child window to it. Examples of owned windows are so-called pop-up windows used for building various dialog panels. The main difference between a dialog box and an owned window is that the child window can be moved only within an area limited by the area of the parent window and an owned window can be moved anywhere within the screen area. The behavior of the parent window influences the behavior of its child and owned windows:
-
When the parent window is minimized or maximized, all its child and owned windows are also hidden or restored.
-
When the parent window is moved, all its child windows move with it (this doesn't relate to owned windows).
-
When the parent window is destroyed, all its child and owned windows are destroyed .
Child windows with the common parent window can overlap. The order, in which such windows are displayed, is called Z-order and can be regulated using special API functions, such as SetWindowPos , DeferWindowPos , and GetNextWindow. Later, I won't concentrate on this topic.
Listing 3.4 shows a program that demonstrates the properties of child and owned windows (Fig. 3.2). When this program is started, its main window appears. When the user clicks the mouse within its client area, two windows appear: the child window and the owned window. To better understand their properties, I recommend that you experiment with these windows.
Listing 3.4: A program that creates a main window and two secondary windows
|
.586P ; Flat memory model .MODEL FLAT, stdcall ;--------------------------------------- ; Constants ; The message that arrives when the window is closed WM_DESTROY equ 2 ; The message that arrives when the window is created WM_CREATE equ 1 ; The message that arrives when the user clicks the left mouse ; button in the client area of the window WM_LBUTTONDOWN equ 201h ; Window properties CS_VREDRAW equ 1h CS_HREDRAW equ 2h CS_GLOBALCLASS equ 4000h WS_OVERLAPPEDWINDOW equ 000CF0000H WS_POPUP equ 80000000h WS_CHILD equ 40000000h STYLE equ CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS BS_DEFPUSHBUTTON equ 1h WS_VISIBLE equ 10000000h WS_CHILD equ 40000000h STYLBTN equ WS_CHILD+BS_DEFPUSHBUTTON+WS_VISIBLE ; Standard icon identifier IDI_APPLICATION equ 32512 ; Cursor identifier IDC_ARROW equ 32512 ; Window display mode -- normal SW_SHOWNORMAL equ 1 ; Prototypes of external procedures EXTERN MessageBoxA@16:NEAR EXTERN CreateWindowExA@48:NEAR EXTERN DefWindowProcA@16:NEAR EXTERN DispatchMessageA@4:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetMessageA016:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN LoadCursorA@8:NEAR EXTERN LoadIconA@8:NEAR EXTERN PostQuitMessage@4:NEAR EXTERN RegisterClassA@4:NEAR EXTERN ShowWindow@8:NEAR EXTERN TranslateMessage@4:NEAR EXTERN UpdateWindow@4:NEAR ; Structures ; Message structure MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS ;---- Window class structure WNDCLASS STRUC CLSSTYLE DD ? CLWNDPROC DD ? CLSCBCLSEX DD ? CLSCBWNDEX DD ? CLSHINST DD ? CLSHICON DD ? CLSHCURSOR DD ? CLBKGROUND DD ? CLMENNAME DD ? CLNAME DD ? WNDCLASS ENDS ;------------------------------------------ ; INCLUDELIB directives for the linker to link libraries includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ;------------------------------------------ ; Data segment _DATA SEGMENT NEWHWND DD 0 MSG MSGSTRUCT <?> WC WNDCLASS <?> HINST DD 0 ; Application descriptor TITLENAME DB 'Child and owned windows', 0 TITLENAMED DB 'Child window', 0 TITLENAMEO DB 'Owned window', 0 CLASSNAME DB 'CLASS32', 0 CLASSNAMED DB 'CLASS321', 0 CLASSNAMEO DB 'CLASS322', 0 _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application descriptor PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX REG_CLASS: ; Fragment in which the main window is registered ; Style MOV [WC.CLSSTYLE], STYLE ; Message-handling procedure MOV [WC.CLWNDPROC], OFFSET WNDPROC MOV [WC.CLSCBCLSEX], 0 MOV [WC.CLSCBWNDEX], 0 MOV EAX, [HINST] MOV [WC.CLSHINST], EAX ;----------Window icon PUSH IDI_APPLICATION PUSH 0 CALL LoadIconA@8 MOV [WC.CLSHICON], EAX ;---------- Window cursor PUSH IDC_ARROW PUSH 0 CALL LoadCursorA@8 MOV [WC.CLSHCURSOR], EAX ;----------Registration of the main window MOV [WC.CLBKGROUND], 17 ; Window color MOV DWORD PTR [WC.CLMENNAME], 0 MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAME PUSH OFFSET WC CALL RegisterClassA@4 ; Fragment in which the child window is registered ; Style MOV [WC.CLSSTYLE], STYLE ; Message-handling procedure MOV [WC.CLWNDPROC], OFFSET WNDPROCD MOV [WC.CLSCBCLSEX], 0 MOV [WC.CLSCBWNDEX], 0 MOV EAX, [HINST] MOV [WC.CLSHINST], EAX ;------------- MOV [WC.CLBKGROUND], 2 ; Window color MOV DWORD PTR [WC.CLMENNAME], 0 MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAMED PUSH OFFSET WC CALL RegisterClassA@4 ; Fragment in which the owned window is registered ; Style MOV [WC.CLSSTYLE], STYLE ; Message-handling procedure MOV [WC.CLWNDPROC], OFFSET WNDPROCO MOV [WC.CLSCBCLSEX], 0 MOV [WC.CLSCBWNDEX], 0 MOV EAX, [HINST] MOV [WC.CLSHINST], EAX ;------------- MOV [WC.CLBKGROUND], 1 ; Window color MOV DWORD PTR [WC.CLMENNAME], 0 MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAMEO PUSH OFFSET WC CALL RegisterClassA@4 ; Create a window of the registered class PUSH 0 PUSH [HINST] PUSH 0 PUSH 0 PUSH 400 ; DY Window height PUSH 600 ; DX Window width PUSH 100 ; Y Coordinate of the top left corner PUSH 100 ; X Coordinate of the top left corner PUSH WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAME ; Window name PUSH OFFSET CLASSNAME ; Window class PUSH 0 CALL CreateWindowExA@48 ; Check for error CMP EAX, 0 JZ _ERR MOV [NEWHWND], EAX ; Window descriptor ;------------------------------------------ PUSH SW_SHOWNORMAL PUSH [NEWHWND] CALL ShowWindow@8 ; Show the newly created window ;------------------------------------------ PUSH [NEWHWND] CALL UpdateWindow@4 ; Redraw the visible part of the window, the WM_PAINT message ; Message-processing loop MSG_LOOP: PUSH 0 PUSH 0 PUSH 0 PUSH OFFSET MSG CALL GetMessageA@16 CMP EAX, 0 JE END_LOOP PUSH OFFSET MSG CALL TranslateMessage@4 PUSH OFFSET MSG CALL DispatchMessageA@4 JMP MSG_LOOP END_LOOP: ; Exit the program (close the process) PUSH [MSG.MSWPARAM] CALL ExitProcess@4 _ERR: JMP END_LOOP ;************************************ ; Main 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_DESTROY JE WMDESTROY CMP DWORD PTR [EBP+0CH], WM_CREATE JE WMCREATE CMP DWORD PTR [EBP+0CH], WM_LBUTTONDOWN JE LB JMP DEFWNDPROC WMCREATE: MOV EAX, 0 JMP FINISH LB: ; Create the child window PUSH 0 PUSH [HINST] PUSH 0 PUSH DWORD PTR [EBP+08H] PUSH 200 ; DY Window height PUSH 200 ; DX Window width PUSH 50 ; Y Coordinate of the top left corner PUSH 50 ; X Coordinate of the top left corner PUSH WS_CHILD OR WS_VISIBLE OR WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAMED ; Window name PUSH OFFSET CLASSNAMED ; Window class PUSH 0 CALL CreateWindowExA@48 ; Create an owned window PUSH 0 PUSH [HINST] PUSH 0 PUSH DWORD PTR [EBP+08H] PUSH 200 ; DY Window height PUSH 200 ; DX Window width PUSH 150 ; Y Coordinate of the top left corner PUSH 250 ; X Coordinate of the top left corner PUSH WS_POPUP OR WS_VISIBLE OR WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAMEO ; Window name PUSH OFFSET CLASSNAMEO ; Window class PUSH 0 CALL CreateWindowExA@48 DEFWNDPROC: PUSH DWORD PTR [EBP+14H] PUSH DWORD PTR [EBP+10H] PUSH DWORD PTR [EBP+0CH] PUSH DWORD PTR [EBP+08H] CALL DefWindowProcA@16 JMP FINISH WMDESTROY: PUSH 0 CALL PostQuitMessage@4 ; WM_QUIT message MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP ;************************************ ; Child window procedure ; Position of parameters in the stack ; [EBP+014H] ; LPARAM ; [EBP+10H] ; WAPARAM ; [EBP+0CH] ; MES ; [EBP+8] ; HWND WNDPROCD PROC PUSH EBP MOV EBP, ESP PUSH EBX PUSH ESI PUSH EDI CMP DWORD PTR [EBP+0CH], WM_DESTROY JE WMDESTROY CMP DWORD PTR [EBP+0CH], WM_CREATE JE WMCREATE JMP DEFWNDPROC WMCREATE: JMP FINISH DEFWNDPROC: PUSH DWORD PTR [EBP+14H] PUSH DWORD PTR [EBP+10H] PUSH DWORD PTR [EBP+0CH] PUSH DWORD PTR [EBP+08H] CALL DefWindowProcA@16 JMP FINISH WMDESTROY: MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROCD ENDP ;************************************ ; Procedure of the owned window ; Position of parameters in the stack ; [EBP+014H] ; LPARAM ; [EBP+10H] ; WAPARAM ; [EBP+0CH] ; MES ; [EBP+8] ; HWND WNDPROCO PROC PUSH EBP MOV EBP, ESP PUSH EBX PUSH ESI PUSH EDI CMP DWORD PTR [EBP+0CH], WM_DESTROY JE WMDESTROY CMP DWORD PTR [EBP+0CH], WM_CREATE JE WMCREATE JMP DEFWNDPROC WMCREATE: JMP FINISH DEFWNDPROC: PUSH DWORD PTR [EBP+14H] PUSH DWORD PTR [EBP+10H] PUSH DWORD PTR [EBP+0CH] PUSH DWORD PTR [EBP+08H] CALL DefWindowProcA@16 JMP FINISH WMDESTROY: MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROCO ENDP _TEXT ENDS END START
|
It is necessary to mention that to translate the program presented in Listing 3.4 using TASM, in addition to the changes that are common and already known to you, it is necessary to add the @@ prefix (the locality indicator) to the names of matching labels from different procedures and to insert the LOCALS directive in the beginning of the program. MASM automatically considers all labels encountered within the procedure as local. In TASM, however, the situation is more complicated. More information on local labels will be provided in Chapters 11 and 12.
Note that for each of the three windows, a separate message-handling procedure is defined. Message-handling procedures for the child and owned windows do not contain a PostQuitMessage command. This is natural, because closing a child or owned window must not initiate program termination. In all other respects, the contents of the window procedures for this window can be the same as for the main (or top-level) window. They can contain controls, have headers, process any messages, and so on.
| ||
| ||
|