The Assembly Programming Master Book
| ||
| ||
|
Now, consider some examples. Listing 2.2 presents a simple program. I recommend that you study it carefully , since it will become a foundation for all materials that you will consider further. The window that appears when this program is started is shown in Fig. 2.1.
Pay special attention to the INCLUDELIB directives. MASM32 provides lots of libraries. For this example, you needed two of them: user32.lib and kernel32.lib.
Now, you need to define the constants and the library procedures.
All these definitions can be found in INCLUDE files supplied with MASM32. I will not use standard INCLUDE files for two reasons: by avoiding this approach, it is much easier to grasp the idea of programming and it simplifies the migration from MASM to TASM.
You must clearly understand the method of window procedure operation because it defines the entire Windows programming paradigm. The aim of this procedure is to ensure the correct reaction of the application to all incoming messages. Let me explain the operation of the application in detail. To begin with, note that unhandled messages must be returned to the system using the DefwindowProcA function. You must handle four messages: WM_CREATE , WM_DESTROY , WM_LBUTTONDOWN , and WM_RBUTTONDOWN . In terms of object-oriented programming, the WM_CREATE and WM_DESTROY messages play the roles of constructor and destructor, respectively. They arrive to the window function when the window is created or destroyed . If you click the small button with the x in the top right corner of the window, the WM_DESTROY message will arrive to the window function. After that, the PostQuitMessage function will be executed, and the WM_QUIT message will be sent to the function. This message will cause the message-handling loop to terminate. Then, the ExitProcess function will execute. This, in turn , will delete the application from the memory.
I'd like to draw your attention to the _ERR label. The jump to this label takes place if an error occurs. Here, it is possible to place an appropriate error message.
Listing 2.2: An example of a simple Windows application (MASM32)
|
.386P ; Flat memory model .MODEL FLAT, stdcall ; Constants ; The message arrives when the window is closed WM_DESTROY equ 2 ; The message arrives when the window is created WM_CREATE equ 1 ; The message arrives if the left mouse button is clicked ; somewhere in the window area WM_LBUTTONDOWN equ 201h ; The message arrives if the right mouse button is clicked ; somewhere in the window area WM_RBUTTONDOWN equ 204h ; Window properties CS_VREDRAW equ 1h CS_HREDRAW equ 2h CS_GLOBALCLASS equ 4000h WS_OVERLAPPEDWINDOW equ 000CF0000H Style equ CS_HREDRAW+CS_VREDRAW+CS_GLOBALCLASS ; Standard icon identifier IDI_APPLICATION equ 32512 ; Cursor identifier IDC_CROSS equ 32515 ; Normal mode of displaying the window 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 GetMessageA@16: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 ; Directives for linking libraries includelib .c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib ;------------------------------------------ ; Structures ; Message structure MSGSTRUCT STRUC MSHWND DD ? ; Identifier of the window ; that received the message MSMESSAGE DD ? ; Message identifier MSWPARAM DD ? ; Auxiliary information about the message MSLPARAM DD ? ; Auxiliary information about the message MSTIME DD ? ; Time of sending the message MSPT DD ? ; Cursor position at the time of sending ; the message MSGSTRUCT ENDS ;------------ WNDCLASS STRUC CLSSTYLE DD ? ; Window style CLWNDPROC DD ? ; Pointer to the window procedure CLSCEXTRA DD ? ; Information on auxiliary bytes for ; this structure CLWNDEXTRA DD ? ; Information on auxiliary bytes for the window CLSHINSTANCE DD ? ; Application descriptor CLSHICON DD ? ; Window icon descriptor CLSHCURSOR DD ? ; Window cursor descriptor CLBKGROUND DD ? ; Window brush descriptor CLMENUNAME DD ? ; Menu identifier CLNAME DD ? ; Specifies the window class name WNDCLASS ENDS ; Data segment _DATA SEGMENT NEWHWND DD 0 MSG MSGSTRUCT <?> WC WNDCLASS <?> HINST DD 0 ; Here, the application descriptor is stored TITLENAME DB 'Simple example of a 32-bit application', 0 CLASSNAME DB 'CLASS32', 0 CAP DB 'Message', 0 MES1 DB 'You have clicked the left mouse button', 0 MES2 DB 'Exit. Bye!', 0 _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get application descriptor PUSH 0 CALL GetModuleHandleA@4 ; MOV [HINST], EAX REG_CLASS: ; Fill window structure ; Style MOV [WC.CLSSTYLE], style ; Message-handling procedure MOV [WC.CLWNDPROC], OFFSET WNDPROC MOV [WC.CLSCEXTRA], 0 MOV [WC.CLWNDEXTRA], 0 MOV EAX, [HINST] MOV [WC.CLSHINSTANCE], EAX ;----------Window icon PUSH IDI_APPLICATION PUSH 0 CALL LoadIconA@8 MOV [WC.CLSHICON], EAX ;----------Window cursor PUSH IDC_CROSS PUSH 0 CALL LoadCursorA@8 MOV [WC.CLSHCURSOR], EAX ;----------- MOV [WC.CLBKGROUND], 17 ; Window color MOV DWORD PTR [WC.CLMENUNAME], 0 MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAME 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 400 ; DX - Window width PUSH 100 ; Y - Coordinate of the window's top left corner PUSH 100 ; X - Coordinate of the window's top left corner PUSH WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAME ; Window name PUSH OFFSET CLASSNAME ; Class name PUSH 0 CALL CreateWindowExA@48 ; Check for errors CMP EAX, 0 JZ _ERR MOV [NEWHWND], EAX ; Window descriptor ;--------------------- PUSH SW_SHOWNORMAL PUSH [NEWHWND] CALL ShowWindow@8 ; Display the newly created window ;------------------------- PUSH [NEWHWND] CALL UpdateWindow@4 ; Redraw the visible part of the window ; WM_PAINT message ; Message-handling 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 ;------------------------------------------ ; 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 ; Left button JE LBUTTON CMP DWORD PTR [EBP+0CH], WM_RBUTTONDOWN ; Right button JE RBUTTON JMP DEFWNDPROC ; Clicking the right mouse button closes the window RBUTTON: JMP WMDESTROY ; Clicking the left mouse button LBUTTON: ; Displaying the message PUSH 0 ; MB_OK PUSH OFFSET CAP PUSH OFFSET MES1 PUSH DWORD PTR [EBP+08H] CALL MessageBoxA@16 MOV EAX, 0 JMP FINISH WMCREATE: MOV EAX, 0 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: PUSH 0 ; MB_OK PUSH OFFSET CAP PUSH OFFSET MES2 PUSH DWORD PTR [EBP+08H] ; Window descriptor CALL MessageBoxA@16 PUSH 0 CALL PostQuitMessage@4 ; WM_QUIT message MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START
|
| ||
| ||
|