| ||
After considering the program shown in Listing 2.2, you might ask a reasonable questionhow do I implement the same program in TASM? Only minor changes are required to achieve this: Instead of using the user32.lib and kernel32.lib libraries, it is necessary to link the import32.lib library, delete the @N suffix from all names of library procedures, and issue the following commands:
tasm32 /ml prog.asm tlink32 -aa prog.obj
:586P ; Flat memory model .MODEL FLAT, stdcall ; Constants ; Message arrives when the window is closed WM_DESTROY equ 2 ; Message arrives when the window is created WM_CREATE equ 1 ; Message when left-clicking the mouse in the window area WM_LBUTTONDOWN equ 201h ; Message when right-clicking the mouse 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 ; Identifier of the standard icon 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:NEAR EXTERN CreateWindowExA:NEAR EXTERN DefWindowProcA:NEAR EXTERN DispatchMessageA:NEAR EXTERN ExitProcess:NEAR EXTERN GetMessageA:NEAR EXTERN GetModuleHandleA:NEAR EXTERN LoadCursorA:NEAR EXTERN LoadIconA:NEAR EXTERN PostQuitMessage:NEAR EXTERN RegisterClassA:NEAR EXTERN ShowWindow:NEAR EXTERN TranslateMessage:NEAR EXTERN UpdateWindow:NEAR ; Directives for the linker to link libraries includelib c:\tasm32\lib\import32.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 when the message was sent 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 structure CLSCEXTRA DD ? ; Information on the auxiliary bytes ; for this structure CLWNDEXTRA DD ? ; Information on the auxiliary bytes ; for the window CLSHINSTANCE DD ? ; Application descriptor CLSHICON DD ? ; Window icon identifier CLSHCURSOR DD ? ; Window cursor identifier CLBKGROUND DD ? ; Window brush identifier 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 'A 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 the application descriptor PUSH 0 CALL GetModuleHandleA MOV [HINST], EAX REG_CLASS: ; Fill the window structure ; Style MOV [WC.CLSSTYLE], style ; Message-handling procedure MOV [WC.CLWNDPROC], OFFSET WNDPROC MOV [WC.CLSCSEXTRA], 0 MOV [WC.CLNDEXTRA], 0 MOV EAX, [HINST] MOV [WC.CLSHINSTANCE], EAX ;----------Window icon PUSH IDI_APPLICATION PUSH 0 CALL LoadIconA MOV [WC.CLSHICON], EAX ;---------- Window cursor PUSH IDC_CROSS PUSH 0 CALL LoadCursorA MOV [WC.CLSHCURSOR], EAX ;---------- MOV [WC.CLBCKGROUND], 17 ; Window color MOV DWORD PTR [WC.CLMENUNAME], 0 MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAME PUSH OFFSET WC CALL RegisterClassA ; Create the 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 ; Window class PUSH 0 CALL CreateWindowExA ; Checking for errors CMP EAX, 0 JZ _ERR MOV [NEWHWND], EAX PUSH SW_SHOWNORMAL PUSH [NEWHWND] CALL ShowWindow ; Show the newly-created window PUSH [NEWHWND] CALL UpdateWindow ; Redraw the visible part ; of the window, the WM_PAINT message ; Message-handling loop MSG_LOOP: PUSH 0 PUSH 0 PUSH 0 PUSH OFFSET MSG CALL GetMessageA CMP EAX, 0 JE END_LOOP PUSH OFFSET MSG CALL TranslateMessage PUSH OFFSET MSG CALL DispatchMessageA JMP MSG_LOOP END_LOOP: ; Exit the program (close the process) PUSH [MSG.MSWPARAM] CALL ExitProcess _ERR: JMP END_LOOP ;--------------------- Window procedure ; Position of the 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 ; Right-clicking the mouse closes the window RBUTTON: JMP WMDESTROY ; Left-clicking the mouse LBUTTON: ; Displaying the message PUSH 0 ; MB_OK PUSH OFFSET CAP PUSH OFFSET MES1 PUSH DWORD PTR [EBP+08H] CALL MessageBoxA 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 JMP FINISH WMDESTROY: PUSH 0 ; MB_OK PUSH OFFSET CAP PUSH OFFSET MES2 PUSH DWORD PTR [EBP+08H] ; Window descriptor CALL MessageBoxA PUSH 0 CALL PostQuitMessage ; WM_QUIT message MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START
By the way, note that the executable module translated using TASM32 is always longer than the similar module translated using MASM32.
Note how window properties are specified. Descriptions of these properties can be found in the help system for the CreateWindow function. Principally, the selection of the required window properties and their combinations is a tedious task. This is one of the reasons why the resources became an integral part of the executable module. The concept of resources will be covered in detail in Chapters 9 and 10.
The examples provided here show that the window procedure must correctly react to the received messages. Later, you'll discover that the window procedure itself can send messages to the application, other windows, and to its own window. [i]
Some API functions have the A suffix. API functions have two prototypes: the ones with the A suffix support ANSI, and the ones with the W suffix support Unicode.
[i] PostQuit is an example illustrating a message sent to the procedure's own window.
| ||