关于
KillTimer 对消息队列中剩余未处理的 WM_TIMER 消息的影响,MSDN 和 Programming Windows 上的说
法完全相反。
MSDN 的说法很干脆:The KillTimer function does not remove WM_TIMER messages
already posted to the message queue. 而 petzold
则说
The KillTimer call purges the
message queue of any pending WM_TIMER messages. Your program will never receive a
stray WM_TIMER message following a KillTimer call. (KillTimer 消除消息队列中任何未处理
的
WM_TIMER 消息,调用 KillTimer
“
”
后你的程序永远不会收到一条 漂泊游荡 的
WM_TIMER 消息)
关于
WM_TIMER
消息
wParam 为计时器的 ID;如果需要设定多个计时器,那么对每个计时器都使用不同的计时器 ID。wParam 的值将
随传递到窗口过程中的
WM_TIMER
消息的不同而不同。
lParam 为指向 TimerProc 的指针,如果调用 SetTimer 时没有指定 TimerProc(参数值为 NULL),则
lParam 为 0(即 NULL)
。
可以通过在窗口过程中提供一个
WM_TIMER case 处理这个消息,或者,默认窗口过程会调用 SetTimer 中指定
的
TimerProc 来处理 WM_TIMER
消息
使用计时器的三种方法
如果在程序的整个执行过程中使用计时器,一般在处理
WM_CREATE 消息时或 WinMain 中消息循环前调用
SetTimer,在处理 WM_DESTROY 消息时或在 WinMain 中消息循环后 return 前调用 KillTimer。根据
SetTimer
中的参数不同,有三种方法使用计时器。
方法一:调用
SetTimer 时指定窗口句柄 hWnd,nIDEvent 中指定计时器 ID,将 lpTimerFunc 置 NULL 从而
不使用
TimerProc;在窗口过程中处理 WM_TIMER 消息。调用 KillTimer 时,使用 SetTimer 中指定的 hWnd
和
id。最好使用#define 定义 timer 的 id
,例如:
#define ID_TIMER 1
SetTimer(hWnd,ID_TIMER,1000,NULL) ;
KillTimer(hWnd,ID_TIMER) ;
方法二:调用
SetTimer 时指定窗口句柄 hWnd,nIDEvent 中指定计时器 ID,lpTimerFunc 参数不为 NULL
而指定为
TimerProc 函数的指针。这种方法使用 TimerProc 函数(名字可自定)处理 WM_TIMER
消息:
VOID CALLBACK TimerProc ( HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
//处理 WM_TIMER
讯息
}
TimerProc 的参数 hwnd 是在调用 SetTimer 时指定的窗口句柄。Windows 只把 WM_TIMER 消息送给
TimerProc,因此消息参数总是等于 WM_TIMER。iTimerID 值是计时器 ID,dwTimer 值是与从
GetTickCount 函数的返回值相容的值。这是自 Windows
启动后所经过的毫秒数。 使用这种方法时,相关函数
调用的形式为:
SetTimer(hWnd,ID_TIMER,1000,TimerProc) ;
KillTimer(hWnd,ID_TIMER) ;
方法三:调用
SetTimer 时不指定窗口句柄(为 NULL),iTimerID 参数自然被忽略,lpTimerFunc 不为 NULL
而指定为
TimerProc 的指针。正如上面 SetTimer 的讨论中所说的,此时 SetTimer 的返回值正是新建立的计
时器的
ID,需将这个 ID 保存以供 KillTimer 销毁计时器时所用。当然,KillTimer 的 hWnd 参数也置为
NULL。这种方法同样用 TimerProc 处理 WM_TIMER
消息。
UINT_PTR iTimerID ;
iTimerID = SetTimer(NULL,0,1000,TimerProc) ;
KillTimer(NULL,iTimerID) ;
使用这种方法的好处是不必自己指定计时器
ID,这样就不必担心用错 ID
。
使用多个计时器