SetTimer:建立計時器KillTimer:銷毀計時器(計時器屬系統資源,用畢必須釋放)UINT_PTR SetTimer(
HWND hWnd, // 關聯視窗控制代碼,必須屬於呼叫執行緒;NULL 表示無視窗關聯
UINT_PTR nIDEvent, // 計時器識別碼(非零);hWnd 為 NULL 時被忽略
UINT uElapse, // 間隔毫秒數(1 ~ 4,294,967,295,近 50 天)
TIMERPROC lpTimerFunc // 回呼函式指標;NULL 時發送 WM_TIMER 至訊息佇列
);
hWnd 非 NULL 且已有相同 nIDEvent 計時器時,新呼叫會取代舊計時器。hWnd 為 NULL 時回傳新計時器 ID;非 NULL 時回傳非零整數;失敗回傳 0。MSDN:KillTimer 不會 移除已佇列的 WM_TIMER 訊息。
Petzold《Windows 程式設計》:KillTimer 會 清除佇列中待處理的 WM_TIMER,呼叫後程式不會收到「流浪」的 WM_TIMER。
實務上建議自行在訊息處理中加入防呆邏輯。
wParam:計時器 IDlParam:指向 TimerProc 的指標;若 SetTimer 時 lpTimerFunc 為 NULL,則為 0#define ID_TIMER 1 SetTimer(hWnd, ID_TIMER, 1000, NULL); KillTimer(hWnd, ID_TIMER); // 在視窗程式中處理 WM_TIMER
VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
// 處理 WM_TIMER
}
SetTimer(hWnd, ID_TIMER, 1000, TimerProc);
KillTimer(hWnd, ID_TIMER);
UINT_PTR iTimerID; iTimerID = SetTimer(NULL, 0, 1000, TimerProc); KillTimer(NULL, iTimerID);
優點:無須自行管理計時器 ID,避免 ID 衝突。
#define TIMER_SEC 1
#define TIMER_MIN 2
SetTimer(hwnd, TIMER_SEC, 1000, NULL);
SetTimer(hwnd, TIMER_MIN, 60000, NULL);
case WM_TIMER:
switch (wParam) {
case TIMER_SEC: /* 每秒處理 */ break;
case TIMER_MIN: /* 每分處理 */ break;
}
return 0;
直接以新間隔值再次呼叫 SetTimer 即可覆蓋現有計時器。
WM_TIMER 為低優先級訊息,僅在佇列無其他訊息時處理。WM_TIMER。WM_TIMER 會合併為一個,導致「遺漏」觸發,無法得知遺漏次數。勿使用計數 WM_TIMER 來計時。時鐘程式應呼叫 GetLocalTime 等系統時間函式取得真實時間,計時器僅用於定時觸發畫面重繪(間隔 ≤ 1 秒)。