background image

使用多个计时器只要在建立计时器时指定不同的

ID

 

。比如用上面所述方法一时的情况:

#define TIMER_SEC 1 

#define TIMER_MIN 2 
然后使用两个

SetTimer

 

来设定两个计时器:

SetTimer (hwnd, TIMER_SEC, 1000, NULL) ; 
SetTimer (hwnd, TIMER_MIN, 60000, NULL) ; 

WM_TIMER

 

的处理如下所示:

case WM_TIMER: 

switch (wParam) 

case TIMER_SEC: 
//

 

每秒一次的处理

break ; 
case TIMER_MIN: 

//

 

每分钟一次的处理

break ; 


return 0 ; 

 

改变计时器的时间间隔

如果想将一个已经存在的计时器设定为不同的时间间隔,可以简单地用不同的时间值再次调用

SetTimer  

 

计时器精确吗?

 

计时器并不精确。有两个原因:

原因一:

Windows 计时器是硬件和 ROM BIOS 架构下之计时器一种相对简单的扩充。回到 Windows 以前的 MS-

DOS 程序写作环境下,应用程式能够通过拦截者称为 timer tick 的 BIOS 中断来实现时钟或计时器。一些为
MS-DOS 编写的程序自己拦截这个硬件中断以实现时钟和计时器。这些中断每 54.915 毫秒产生一次,或者大约每

18.2 次。这是原始的 IBM PC 的微处理器频率值 4.772720 MHz 被 218 所除而得出的结果。在 Windows 98

中,计时器与其下的

PC 计时器一样具有 55 毫秒的解析度。在 Microsoft Windows NT 中,计时器的解析度为

10 毫秒。Windows 应用程式不能以高于这些解析度的频率(在 Windows 98 下,每秒 18.2 次,在 Windows 
NT 下,每秒大约 100 次)接收 WM_TIMER 消息。在 SetTimer 中指定的时间间隔总是截尾后 tick 数的整数倍。
例如,

1000 毫秒的间隔除以 54.925 毫秒,得到 18.207 个 tick,截尾后是 18 个 tick,它实际上是 989 毫秒。

对每个小于

55 毫秒的间隔,每个 tick 都会产生一个 WM_TIMER

 

消息。

可见,计时器并不能严格按照指定的时间间隔发送

WM_TIMER

 

消息,它总要相差那么几毫秒。

 

即使忽略这几个毫秒的差别,计时器仍然不精确。请看原因二:
WM_TIMER 消息放在正常的消息队列之中,和其他消息排列在一起,因此,如果在 SetTimer 中指定间隔为 1000
毫秒,那么不能保证程序每

1000 毫秒或者 989 毫秒就会收到一个 WM_TIMER 消息。如果其他程序的执行事件超

过一秒,在此期间内,您的程式将收不到任何

WM_TIMER

 

讯息。事实上,

Windows 对 WM_TIMER 消息的处理非

常类似于对

WM_PAINT 消息的处理,这两个消息都是低优先级的,程序只有在消息队列中没有其他消息时才接收

 

它们。
WM_TIMER 还在另一方面和 WM_PAINT 相似:Windows 不能持续向消息队列中放入多个 WM_TIMER 讯息,而是将
多余的

WM_TIMER 消息组合成一个消息。因此,应用程序不会一次收到多个这样的消息,尽管可能在短时间内得

到两个

WM_TIMER 消息。应用程序不能确定这种处理方式所导致的 WM_TIMER

 

消息「遗漏」的数目。

可见,

WM_TIMER 消息并不能及时被应用程序所处理,WM_TIMER 在消息队列中的延误可能就不能用毫秒来计算

 

了。

由以上两点,你不能通过在处理

WM_TIMER 时一秒一秒计数的方法来计时。如果要实现一个时钟程序,可以使用

系统的时间函数如

GetLocalTime ,而在时钟程序中,计时器的作用是定时调用 GetLocalTime 获得新的时间

并刷新时钟画面,当然这个刷新的间隔要等于或小于

1 秒。