
- •Оглавление
- •1 Введение
- •2 Цель работы
- •3 Теоретические сведения о таймерахWindows
- •2. Временной интервал, который вы задаете при вызове функции SetTimer всегда округляется вниз до целого числа кратного частоте
- •4 Описание используемыхWinApIфункций
- •5 Текст программы
- •6 Результаты работы
- •7 Выводы
- •8 Литература
5 Текст программы
Файл ресурсов создан с помощью средств программы ResEDIT.
// файл timer.rc
// определение констант
#define WS_SYSMENU 0x00080000L
#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L
// стиль - кнопка
#define BS_PUSHBUTTON 0x00000000L
// кнопка в окне должна быть видимой
#define WS_VISIBLE 0x10000000L
// центрировать текст на кнопке
#define BS_CENTER 0x00000300L
// стиль кнопки
#define WS_CHILD 0х40000000L
// возможность фокусировать элемент
// при помощи клавиши TAB
#define WS_TABSTOP 0x00010000L
#define DS_3DLOOK 0x0004L
//определение диалогового окна
DIAL1 DIALOG 0, 0, 240, 120
STYLE WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | DS_3DLOOK
CAPTION "Пример диалогового окна с таймером"
FONT 8, "Arial"
{
// кнопка, идентификатор 5
CONTROL "Выход", 5, "button", BS_PUSHBUTTON
| BS_CENTER | WS_CHILD | WS_VISIBLE | WS_TABSTOP,
180, 76, 50, 14
}
; файл timer.inc
; константы
; сообщение приходит при закрытии окна
WM_CLOSE equ 10h
WM_INITDIALOG equ 110h
WM_COMMAND equ 111h
WM_TIMER equ 113h
; прототипы внешних процедур
IFDEF MASM
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
ELSE
EXTERN ReleaseDC:NEAR
EXTERN GetDC:NEAR
EXTERN TextOutA:NEAR
EXTERN MessageBoxA:NEAR
EXTERN ExitProcess:NEAR
EXTERN GetModuleHandleA:NEAR
EXTERN DialogBoxParamA:NEAR
EXTERN EndDialog:NEAR
EXTERN SendMessageA:NEAR
EXTERN SetTimer:NEAR
EXTERN KillTimer:NEAR
ReleaseDC@8 = ReleaseDC
GetDC@4 = GetDC
TextOutA@20 = TextOutA
MessageBoxA@16 = MessageBoxA
ExitProcess@4 = ExitProcess
GetModuleHandleA@4 = GetModuleHandleA
DialogBoxParamA@20 = DialogBoxParamA
EndDialog@8 = EndDialog
SendMessageA@16 = SendMessageA
SetTimer@16 = SetTimer
KillTimer@8 = KillTimer
ENDIF
; структуры
; структура сообщения
MSGSTRUCT STRUC
MSHWND DD ?
MSMESSAGE DD ?
MSWPARAM DD ?
MSLPARAM DD ?
MSTIME DD ?
MSPT DD ?
MSGSTRUCT ENDS
; файл timer.asm
.386P
; плоская модель
.MODEL FLAT, stdcall
include timer.inc
; директивы компоновщику для подключения библиотек
IFDEF MASM
; для компоновщика LINK.EXE
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\gdi32.lib
ELSE
; для компоновщика TLINK32.EXE
includelib c:\tasm32\lib\import32.lib
ENDIF
;-------------------------------------------------
; сегмент данных
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
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 DWORD PUBLIC USE32 'CODE'
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+014Н] ; LPARAM
; [EBP+10Н] ; 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