| ||
In this section, I demonstrate that the called procedure written in Assembly language can contain not only auxiliary procedures but also calls to application programming interface (API) functions. Furthermore, it can work with resources. Note that these resources are common for all modules of the project. It is possible to have several resource files. The only thing that you'll have to do is ensuring that the names and the identifiers match.
#include <windows. h> #include <stdio.h> // Declare the external function extern "C"__stdcall DIAL1(); void main() { DIAL1(); ExitProcess(0); }
// The DIALFORC.RC file // Definitions of constants #define WS_SYSMENU 0x00080000L // Window elements must be initially visible #define WS_VISIBLE 0x10000000L // Border around the elements #define WS_BORDER 0x00800000L // Elements can be sequentially activated //by pressing the <Tab> key #define WS_TABSTOP 0x00010000L // Text in the edit field is // aligned to the left side #define ES_LEFT 0x0000L // Style of all window elements #define WS_CHILD 0x40000000L // Keyboard input is disabled #define ES_READONLY 0x0800L #define DS_3DLOOK 0x0004L // Dialog box definition DIAL1 DIALOG 0, 0, 240, 100 STYLE WS_SYSMENU DS_3DLOOK CAPTION "An example dialog box with date and time" FONT 8, "Arial" { CONTROL "", 1, "edit", ES_LEFT WS_CHILD WS_VISIBLE WS_BORDER WS_TABSTOP ES_READONLY, 100, 5, 130, 12 } ; The DIALFORC.INC file ; Constants ; This message arrives when the window is closed WM_CLOSE equ 10h ; This message arrives when the window is created WM_INITDIALOG equ 110h ; This message arrives when some event occurs to the window element WM_COMMAND equ 111h ; Message from the timer WM_TIMER equ 113h ; The message for sending some text to the window element WM_SETTEXT equ 0Ch ; Prototypes of external procedures EXTERN SendDlgItemMessageA:NEAR EXTERN _wsprintfA:NEAR EXTERN GetLocalTime:NEAR EXTERN ExitProcess:NEAR EXTERN GetModuleHandleA:NEAR EXTERN DialogBoxParamA:NEAR EXTERN EndDialog:NEAR EXTERN SetTimer:NEAR EXTERN KillTimer:NEAR ; Structures ; Message structure MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS ; Date-time data structure DAT STRUC year DW ? month DW ? dayweek DW ? day DW ? hour DW ? min DW ? sec DW ? msec DW ? DAT ENDS ; The DIALFORC.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall include dialforc.inc PUBLIC DIAL1 ;-------------------------------------- ; Data segment _DATA SEGMENT MSG MSGSTRUCT <?> HINST DD 0 ; Application descriptor PA DB "DIAL1", 0 TIM DB "Date %u/%u/%u Time %u:%u:%u", 0 STRCOPY DB 50 DUP (?) DATA DAT <0> _DATA ENDS ; Code segment _TEXT SEGMENT DIAL1 PROC PUSH EBP MOV EBP, ESP ; Get the application descriptor PUSH 0 CALL GetModuleHandleA MOV [HINST], EAX ; Create a dialog PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL DialogBoxParamA CMP EAX, -1 ;--------------------------------- POP EBP RET DIAL1 ENDP ;--------------------------------- ; Window procedure ; Position of parameters in the stack ; [BP+014H] ; LPARAM ; [BP+10H] ; WAPARAM ; [BP+0CH] ; MES ; [BP+8] ; HWND WNDPROC PROC PUSH EBP MOV EBP, ESP PUSH EBX PUSH ESI PUSH EDI ;---------------- CMP DWORD PTR [EBP+0CH], WM_CLOSE JNE L1 ; Reaction to closing a window ; Delete timer 1 PUSH 1 ; Timer identifier PUSH DWORD PTR [EBP+08H] CALL KillTimer ; Delete timer 2 PUSH 2 ; Timer identifier PUSH DWORD PTR [EBP+08H] CALL KillTimer ; Close the dialog PUSH 0 PUSH DWORD PTR [EBP+08H] CALL EndDialog JMP FINISH L1: CMP DWORD PTR [EBP+0CH], WM_INITDIALOG JNE L2 ; Startup initialization ; Set timer 1 PUSH 0 ; Parameter = NULL PUSH 1000 ; 1-second interval PUSH 1 ; Timer identifier PUSH DWORD PTR [EBP+08H] CALL SetTimer ; Set timer 2 PUSH OFFSET TIMPROC ; Parameter = NULL PUSH 500 ; 0.5-second interval PUSH 2 ; Timer identifier PUSH DWORD PTR [EBP+08H] CALL SetTimer JMP FINISH L2: CMP DWORD PTR [EBP+0CH], WM_TIMER JNE FINISH ; Send the string to the window PUSH OFFSET STRCOPY PUSH 0 PUSH WM_SETTEXT PUSH 1 ; Element identifier PUSH DWORD PTR [EBP+08H] CALL SendDlgItemMessageA FINISH: POP EDI POP ESI POP EBX POP EBP MOV EAX, 0 RET 16 WNDPROC ENDP ;------------------------------------------- ; Timer procedure ; Position of parameters in the stack ; [BP+014H] ; LPARAM --- Time elapsed since Windows startup ; [BP+10H] ; WAPARAM - Timer identifier ; [BP+0CH] ; WM_TIMER ; [BP+8] ; HWND TIMPROC PROC PUSH EBP MOV EBP, ESP ; Get the local time PUSH OFFSET DATA CALL GetLocalTime ; Get the string for date and time output MOVZX EAX, DATA.sec PUSH EAX MOVZX EAX, DATA.min PUSH EAX MOVZX EAX, DATA.hour PUSH EAX MOVZX EAX, DATA.year PUSH EAX MOVZX EAX, DATA.month PUSH EAX MOVZX EAX, DATA.day PUSH EAX PUSH OFFSET TIM PUSH OFFSET STRCOPY CALL _wsprintfA ; Restore the stack ADD ESP, 32 POP EBP RET 16 TIMPROC ENDP _TEXT ENDS END
To translate this program, proceed as follows :
First methodIssue the following commands:
tasm32 /ml dialforc.asm brcc32 dialforc.rc
Then, include the DIALFORC.OBJ and DIALFORC.RES files in the project.
Second methodThis method differs from the previous one in that the DIALFORC.RC file is included in the project instead of the DIALFORC.RES file. Naturally, it is necessary to remove definitions of constants from that file because all required definitions are in the C header files.
| ||