使用计时器只需要了解两个函数。CWnd::SetTimer用于产生以指定时间间隔发送消息的计时器,CWnd::KillTimer则消除计时器。
使用计时器的两种方法:
设置计时器最简单的方法是用计时器ID和计时器时间间隔来调用SetTimer,然后WM_TIMER消息映射给OnTimer函数。例如:
#define TIMER_ID1 1
#define TIMER_ID2 2
SetTimer(TIMER_ID1, 100, NULL);
SetTimer(TIMER_ID2, 5000, NULL);
通常,我们将SetTimer的操作放在窗口的OnCreate函数中,当然也可以根据需要放在其他位置。
MFC的ON_WM_TIMER消息映射表宏将WM_TIMER消息映射给了类成员函数OnTimer。OnTimer的原形如下,
afx_msg void OnTimer(UINT nTimerID);
其中,nTimerID是产生消息的计时器的ID。可以在OnTimer 中时行消息响应。
可以设置一个使用回调函数的计时器,即在SetTimer的第3个参数中指定回调函数的名字,例如:
SetTimer(ID_TIMER, 100, TimerProc);
上面名字为TimerProc的回调函数的原形如下:
Void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nTimerID, DWORD dwTimer);
其中,hWnd参数保存窗口句柄,nMsg保存消息ID WM_TIMER,nTimerID保存计时器ID,而dwTimer指定从Windows启动以后经过时间的毫秒数。
回调函数应该是一个静态成员函数或是全局函数,防止this指针传递给它。
与CWnd::SetTimer对应的是CWnd::KillTimer,它清除计时器并停止计时器消息。下面语句释放ID为1的计时器:
KillTimer(1);
窗口的OnClose或OnDestroy函数是清除OnCreate创建的计时器的好地方。
WM_TIMER消息永远不会中断同一个线程中的另一个WM_TIMER消息,也不会中断非计时器消息。WM_TIMER消息被放在正常的消息队列中,并和其他消息一同排队等候处理。事实上,Windows处理WM_TIMER消息和WM_PAINTI很类似,这两种消息都是低优先级的,只有当消息队列中没有其他消息时,程序才会收到它们。
如果程序处于忙的状态,则在该时间内程序得不到任何WM_TIMER消息。若要编写一个时钟应用程序,安排计时为1000毫秒间隔并在每次WM_TIMER消息到达时更新显示,则不应该假定60个WM_TIMER消息就意味逝去了一分钟。实际上,应该在每次消息到达时都检查当前时间并更新时钟,这样才可以维持时钟的精确显示。
SetTimer参数中指定的时间间隔,其有效值从1毫秒到232-1毫秒。但大多数系统中,Windows计时器基于的硬件计时器每54.9毫秒走一下。因此,语句
SetTimer(1, 1,NULL);
安排计时器大约每55毫秒发送一个WM_TIMER消息。语句
SetTimer(1, 60,NULL);
则是每110毫秒发送一个WM_TIMER消息。