第6章 定时器和windows时间
2020-12-29 本文已影响0人
sunnnnnnnnnny
1 定时器
相关api
//设置定时器
SetTimer
UINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procedure 当为NULL时会向窗口发送VM_TIMER消息
);
WM_TIMER 消息的附加参数
wTimerID = wParam; // timer identifier
tmprc = (TIMERPROC *) lParam; // address of timer callback
//撤销定时器
KillTimer
BOOL KillTimer(
HWND hWnd, // handle of window that installed timer
UINT uIDEvent // timer identifier
);
源代码
Timer.rc
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <resource.h>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define DLG_MAIN 1
#define ICO_1 1
#define ICO_2 2
#define IDC_SETICON 100
#define IDC_COUNT 101
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//定义了两个icon
ICO_1 ICON "1.ico" //对话框的图标,会取第一个ICON
ICO_2 ICON "2.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//定义一个对话框 name DIALOG x,y,w,h
DLG_MAIN DIALOG 50, 50, 113, 40
//对话框的style
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "定时器例子" //对话框标题
FONT 9, "宋体" //对话框字体
{
ICON ICO_1, IDC_SETICON, 8, 9, 18, 21
LTEXT "计数:", -1, 35, 16, 25, 10
LTEXT "", IDC_COUNT, 62, 16, 40, 10
}
汇编代码
Timer.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 3rd Edition>
; by 罗云彬, http://www.win32asm.com.cn
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Timer.asm
; 定时器的使用例子
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff Timer.asm
; rc Timer.rc
; Link /subsystem:windows Timer.obj Timer.res
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ID_TIMER1 equ 1
ID_TIMER2 equ 2
ICO_1 equ 1
ICO_2 equ 2
DLG_MAIN equ 1
IDC_SETICON equ 100
IDC_COUNT equ 101
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
dwCount dd ?
idTimer dd ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 定时器过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcTimer proc _hWnd,_uMsg,_idEvent,_dwTime
PUSHAD ;将通用寄存器压栈 入栈顺序为EAX,ECX,EDX,EBX,ESP(初始值),EBP,ESI,EDI.
invoke GetDlgItemInt,hWinMain,IDC_COUNT,NULL,FALSE
; GetDlgItemInt 获取对话框指定控件文本,将其转换为整数
;UINT GetDlgItemInt(
; HWND hDlg, // handle to dialog box
; int nIDDlgItem, // control identifier
; BOOL *lpTranslated, // points to variable to receive success/failure indicator
; BOOL bSigned // specifies whether value is signed or unsigned
; );
inc eax
invoke SetDlgItemInt,hWinMain,IDC_COUNT,eax,FALSE
;BOOL SetDlgItemInt(
; HWND hDlg, // handle of dialog box
; int nIDDlgItem, // identifier of control
; UINT uValue, // value to set
; BOOL bSigned // signed or unsigned indicator
; );
POPAD ;将通用寄存器恢复
ret
_ProcTimer endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
mov eax,uMsg
;********************************************************************
.if eax == WM_TIMER
;处理WM_TIMER
;WM_TIMER 消息的附加参数
;wTimerID = wParam; // timer identifier
;tmprc = (TIMERPROC *) lParam; // address of timer callback
;
mov eax,wParam ;将定时器ID放入eax
.if eax == ID_TIMER1 ;若是第1个定时器
inc dwCount ;dwCount加1
;取dwCount的第1位 0/1
mov eax,dwCount
and eax,1 ;eax=0 or 1
inc EAX ;eax=1 or 2 对应ICO_1 ICO_2
invoke LoadIcon,hInstance,EAX ;加载icon
;修改ICON控件IDC_SETICON的图标
invoke SendDlgItemMessage,hWnd,IDC_SETICON,STM_SETIMAGE,IMAGE_ICON,EAX
;LONG SendDlgItemMessage(
; HWND hDlg, // handle of dialog box
; int nIDDlgItem, // identifier of control
; UINT Msg, // message to send
; WPARAM wParam, // first message parameter
; LPARAM lParam // second message parameter
;);
;STM_SETIMAGE消息的附带参数
;wParam = (WPARAM) fImageType; // image-type flag IMAGE_ICON/IMAGE_BITMAP/...
;lParam = (LPARAM) (HANDLE) hImage; // handle of the image
.elseif eax == ID_TIMER2 ;若是第2个定时器
invoke MessageBeep,-1 ;调用蜂鸣器
.endif
;********************************************************************
.elseif eax == WM_INITDIALOG ;窗口初始化时
push hWnd
pop hWinMain ;将hWnd赋值给hWinMain
invoke SetTimer,hWnd,ID_TIMER1,250,NULL ;创建定时器ID_TIMER1 周期为250ms
invoke SetTimer,hWnd,ID_TIMER2,2000,NULL ;创建定时器ID_TIMER2 周期为2s
invoke SetTimer,NULL,NULL,1000,addr _ProcTimer ;创建定时器ID_TIMER3 周期为1s 定时器回调函数为_ProcTimer
mov idTimer,EAX ;将第3个定时器的id保存至idTimer
;********************************************************************
.elseif eax == WM_CLOSE
;在窗口退出之前撤销3个定时器
invoke KillTimer,hWnd,ID_TIMER1
invoke KillTimer,hWnd,ID_TIMER2
invoke KillTimer,NULL,idTimer
;结束对话框
invoke EndDialog,hWnd,NULL
;********************************************************************
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
Makefile
NAME = Timer
OBJS = $(NAME).obj
RES = $(NAME).res
LINK_FLAG = /subsystem:windows
ML_FLAG = /c /coff
$(NAME).exe: $(OBJS) $(RES)
Link $(LINK_FLAG) $(OBJS) $(RES)
.asm.obj:
ml $(ML_FLAG) $<
.rc.res:
rc $<
clean:
del *.obj
del *.res
2 windows时间
2.1 windows时间的获取和设置
GetLocalTime SYSTEMTIME
GetSystemTime
2.2 计算时间间隔
GetTickCount