计时器
见钱眼开 于
2005-5-4
Windows计时器是一种输入设备,周期性的每经过一个指定的时间间隔就通知应用程序一次。你的程序将时间间隔告诉Windows,然后Windows给您的程序周期性发生的WM_TIMER消息以表示时间到了。
很多重要的软件功能都是通过计时器实现的。例如,系统时钟就是个最典型的例子。
使用SetTimer函数实现分配一个计时器。可设定的时间间隔可以是1-2
32毫秒(将近50天)之间的任何值。调用KillTimer函数结束使用一个计时器。
Windows
计时器是
PC
的硬件和
ROM BIOS
构造的计时器逻辑的一种相对简单的扩展。
DOS
时代,应用程序一般都是通过捕获
BIOS
中断来实现时钟或计时器,这些中断每
54.915
毫秒产生一次。而
Windows
应用程序不需要捕获
BIOS
中断,
Windows
本身处理硬件中断。
Windows
为每个应用程序的计时器保存一个计数,当计数减少为
0
时,
Windows
在相应的应用程序消息队列中放置一个
WM_TIMER
消息,并将计数恢复为初始值。
在
Windows98
中,计时器与潜在的
PC
计时器一样具有
55
毫秒的分辨率。在
Windows NT
中,计时器的分辨率为
10
毫秒。
Windows
应用程序不可能以高于这一分辨率的速率接收
WM_TIMER
消息。在
SetTimer
中指定的时间间隔总是截尾为时钟嘀嗒的整数倍。例如,
1000
毫秒的间隔除以
54.925
毫秒,得到
18.207
个时钟嘀嗒,截尾后为
18
个时钟嘀嗒,它实际上是
989
毫秒。对于小于
55
毫秒的间隔。每个时钟嘀嗒都产生一个
WM_TIMER
消息。
计时器是基于硬件计时器中断的,但是
Windows
程序却并非以异步的方式中断处理
WM_TIMER
消息。
WM_TIMER
消息被放置在消息队列,和其他消息一起参加排序。而且,
Windows
对于
WM_TIEMR
消息的处理类似于
WM_PAINT
消息,都是低优先级的,只有在消息队列中没有其他消息时才接收它们。
WM_TIEMR
消息和
WM_PAINT
消息还有一点相同,
Windows
不会连续向消息队列放置多个
WM_TIMER
消息,总是将多余的
WM_TIMER
消息合成一个消息
。
WM_TIMER
消息
wParam
参数代表计时器
ID
,
lParam
参数包含
SetTimer
函数
lpTimerFunc
参数中指定的计时器回调函数指针,如果未设置回调函数,则该参数值为
0
。
SetTimer
函数声明原型:
UINT_PTR SetTimer(
HWND hWnd, //拥有该计时器的窗口句柄
UINT_PTR nIDEvent, //计时器
ID
UINT uElapse, //时间间隔
TIMERPROC lpTimerFunc //计时器回调函数指针
);
TIMERPROC指向函数原型:
void
CALLBACK TimerProc(
HWND hwnd, //
目标窗口句柄
UINT message, //WM_TIMER
UINT iTimerID, //
计时器
ID
DWORD dwTime, //
自系统启动后所经过的毫秒数,由
GetTickCount
返回
);
计时器使用的三种方法:
a)
指定窗口句柄、计时器
ID
、时间间隔,设置计时器回调函数指针值为
NULL
。在窗口过程中处理
WM_TIMER
消息。
SetTimer(hwnd,Timer_ID,1000,NULL);
b)
指定窗口句柄、计时器
ID
、时间间隔、回调函数。直接由回调函数而不是窗口过程处理
WM_TIMER
消息。
SetTimer(hwnd,Timer_ID,1000,TimerProc);
c)
设置窗口句柄为
NULL
,忽略计时器
ID
,指定时间间隔、回调函数,返回一个计时器
ID
。
如果没有可用的计时器,那么返回值为
NULL
。
UINT uiTimerID = SetTimer(NULL,0,1000,TimerProc);
如果修改一个计时器的时间间隔,设置新的时间间隔后再次调用SetTimer函数即可。
GetSystemTime
函数返回当前的世界时间;
GetLocalTime
函数返回当地时间,取决于计算机位于的时区。它们返回的时间指针都指向一个
SYSTEMTIME
结构,其原型声明如下:
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek; //Sunday = 0, Monday = 1, and so on
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
WORD wYear;
WORD wMonth;
WORD wDayOfWeek; //Sunday = 0, Monday = 1, and so on
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;