;файл prog.asm
.586P
;плоская модель памяти
.MODEL FLAT, stdcall
;константы
;сообщение приходит при закрытии окна
WM_CLOSE equ 10h
WM_INITDIALOG equ 110h
WM_COMMAND equ 111h
WM_TIMER equ 113h
;прототипы внешних процедур
EXTERN ReleaseDC@8:NEAR
EXTERN GetDC@4:NEAR
EXTERN TextOutA@20:NEAR
EXTERN MessageBoxA@16:NEAR
EXTERN ExitProcess@4:NEAR
EXTERN GetModuleHandleA@4:NEAR
EXTERN DialogBoxParamA@20:NEAR
EXTERN EndDialog@8:NEAR
EXTERN SendMessageA@16:NEAR
EXTERN SetTimer@16:NEAR
EXTERN KillTimer@8:NEAR
;структура сообщения
MSGSTRUCT STRUC
MSHWND DD ?
MSMESSAGE DD ?
MSWPARAM DD ?
MSLPARAM DD ?
MSTIME DD ?
MSPT DD ?
MSGSTRUCT ENDS
;директивы компоновщику для подключения библиотек
;для компоновщика LINK.EXE
includelib f:\masm32\lib\user32.lib
includelib f:\masm32\lib\kernel32.lib
includelib f:\masm32\lib\gdi32.lib
;--------------------------------
;сегмент данных
_DATA SEGMENT
MSG MSGSTRUCT <>
HINST DD 0 ;дескриптор приложения
PA DB "DIAL1",0
COUNT DD 0
TEXT DB 0
CAP DB 'Сообщение',0
MES DB 'Выход по таймеру',0
_DATA ENDS
;сегмент кода
_TEXT SEGMENT
START:
;получить дескриптор приложения
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
KOL:
;--------------------------------
PUSH 0
CALL ExitProcess@4
;--------------------------------
;процедура окна
;расположение параметров в стеке
; [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
;здесь реакция на закрытие окна
L3:
;удалить таймер
PUSH 1;идентификатор таймера
PUSH DWORD PTR [EBP+08H]
CALL KillTimer@8
;закрыть диалог
PUSH 0
PUSH DWORD PTR [EBP+08H]
CALL EndDialog@8
JMP FINISH
L1:
CMP DWORD PTR [EBP+0CH],WM_INITDIALOG
JNE L5
;здесь начальная инициализация
;установить таймер
PUSH 0;параметр = NULL
PUSH 1000;интервал 1 с.
PUSH 1;идентификатор таймера
PUSH DWORD PTR [EBP+08H]
CALL SetTimer@16
JMP FINISH
L5:
CMP DWORD PTR [EBP+0CH],WM_COMMAND
JNE L2
;кнопка выхода?
CMP WORD PTR [EBP+10H],5
JNE FINISH
JMP L3
L2:
CMP DWORD PTR [EBP+0CH],WM_TIMER
JNE FINISH
;не пора ли заканчивать?
CMP COUNT,9
;выход без предупреждения
JA L3
;выход через сообщение
JE L4
;пришло сообщение таймера
;подготовить текст
MOV EAX,COUNT
ADD EAX,49
MOV TEXT,AL
;получить контекст
PUSH DWORD PTR [EBP+08H]
CALL GetDC@4
;запомнить контекст
PUSH EAX
;вывести значение счетчика
PUSH 1
PUSH OFFSET TEXT
PUSH 10
PUSH 10
PUSH EAX
CALL TextOutA@20
;удалить контекст
POP EAX
PUSH EAX
PUSH DWORD PTR [EBP+08H]
CALL ReleaseDC@8
;увеличить счетчик
INC COUNT
JMP FINISH
L4:
INC COUNT
;сообщение о выходе по таймеру
PUSH 0
PUSH OFFSET CAP
PUSH OFFSET MES
PUSH DWORD PTR [EBP+08H] ;дескриптор окна
CALL MessageBoxA@16
JMP L3
FINISH:
POP EDI
POP ESI
POP EBX
POP EBP
MOV EAX,0
RET 16
WNDPROC ENDP
;--------------------------------
_TEXT ENDS
END START