周期性的發送WWL_TIMER消息的一個東西,這個周期可以由程序員自己設定。
設定周期的數是SetTimer,停止定時器消息發送的函數是:Killximer;
定時器消息的特點:
1.不准確(也就是說,你設定的周期是1秒,那么有可能在980毫秒的時候,這個WM_TIMER消息就來了,也有可能1010毫秒的時候才來)
2.可能被合並(這個和WL_PAINT消息類似);
SetTimer
UINT_PTR WINAPI SetTimer(
_In_opt_ HWND hWnd,
_In_ UINT_PTR nIDEvent,
_In_ UINT uElapse,
_In_opt_ TIMERPROC lpTimerFunc
);
hWnd: 指向一個和定時器關聯的窗口。如果想改變一個窗口原有定時器的周期,那么這個bwnd必須傳遞NULL。
nIDEvent: 定時器的標識;
uElapse: 定義周期(毫秒)
lpTimerFunc:指向一個函數的指針,如果這個函數指針是NULL,那么定時器周期性發送WA_TIMER消息給窗口,否則,定時器周期性的調用這個函數,不再發送WM_TIMER消息。函數原型:
TimerProc
VOID CALLBACK TimerProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ UINT_PTR idEvent,
_In_ DWORD dwTime
);
hwnd: 和定時器相關聯的窗口
uMsg: L_TIMER
idEvent: 定時器標識
dwTime: 系統啟動后,運行了多長時間(毫秒)
KillTimer
BOOL WINAPI KillTimer(
_In_opt_ HWND hWnd,
_In_ UINT_PTR uIDEvent
);
hwnd:和定時器關聯的窗口;
uIDEvent:定時器標識;
WM_TIMER:
wParam:定時器標識
lParam: 指向回調函數 TimerProc的指針
實現定時器源碼——法一:WM_TIMER

1 #include<Windows.h> 2 #include<WinUser.h> 3 #include<tchar.h> 4 #include<stdio.h> 5 6 #define SECOND 1000 7 #define MINUTE 60000 8 #define HOUR 3600000 9 10 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 11 12 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow) 13 { 14 WNDCLASS WndClass; 15 TCHAR* ClassName = TEXT("MyClass"); 16 HWND hwnd; 17 MSG msg; 18 19 WndClass.cbClsExtra = 0; 20 WndClass.cbWndExtra = 0; 21 WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 22 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 23 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 24 WndClass.hInstance = hInst; 25 WndClass.lpfnWndProc = WindProc; 26 WndClass.lpszClassName = ClassName; 27 WndClass.lpszMenuName = NULL; 28 WndClass.style = CS_VREDRAW | CS_HREDRAW; 29 30 RegisterClass(&WndClass); 31 hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL); 32 ShowWindow(hwnd, nShow); 33 UpdateWindow(hwnd); 34 35 while (GetMessage(&msg, NULL, 0, 0)) 36 { 37 TranslateMessage(&msg); 38 DispatchMessage(&msg); 39 } 40 return 0; 41 } 42 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 43 { 44 HDC hdc; 45 PAINTSTRUCT pt; 46 static int second, minute, hour; 47 static TCHAR str[1024] = { 0 }; 48 switch (message) 49 { 50 case WM_CREATE: 51 SetTimer(hwnd, 1, SECOND, NULL); 52 SetTimer(hwnd, 2, MINUTE, NULL); 53 SetTimer(hwnd, 3, HOUR, NULL); 54 second = 0; 55 minute = 0; 56 hour = 0; 57 return 0; 58 case WM_SIZE: 59 return 0; 60 case WM_PAINT: 61 hdc = BeginPaint(hwnd, &pt); 62 Rectangle(hdc, 10, 10, 100, 30); 63 _stprintf(str, TEXT("%d:%d:%d"), hour, minute, second); 64 TextOut(hdc, 13, 11, str, _tcslen(str)); 65 EndPaint(hwnd, &pt); 66 return 0; 67 case WM_TIMER: 68 if (wParam == 1) 69 { 70 second++; 71 second = second >= 60 ? 0 : second; 72 } 73 else if (wParam == 2) 74 { 75 minute++; 76 minute = minute >= 60 ? 0 : minute; 77 } 78 else 79 hour++; 80 InvalidateRect(hwnd, NULL, TRUE); 81 return 0; 82 case WM_DESTROY: 83 KillTimer(hwnd, 1); 84 KillTimer(hwnd, 2); 85 KillTimer(hwnd, 3); 86 PostQuitMessage(0); 87 return 0; 88 default: 89 break; 90 } 91 92 return DefWindowProc(hwnd, message, wParam, lParam); 93 }
實現定時器源碼——法二:TimerProc

1 #include<Windows.h> 2 #include<WinUser.h> 3 #include<tchar.h> 4 #include<stdio.h> 5 6 #define SECOND 1000 7 #define MINUTE 60000 8 #define HOUR 3600000 9 int second, minute, hour; 10 11 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 12 VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); 13 14 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow) 15 { 16 WNDCLASS WndClass; 17 TCHAR* ClassName = TEXT("MyClass"); 18 HWND hwnd; 19 MSG msg; 20 21 WndClass.cbClsExtra = 0; 22 WndClass.cbWndExtra = 0; 23 WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 24 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 25 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 26 WndClass.hInstance = hInst; 27 WndClass.lpfnWndProc = WindProc; 28 WndClass.lpszClassName = ClassName; 29 WndClass.lpszMenuName = NULL; 30 WndClass.style = CS_VREDRAW | CS_HREDRAW; 31 32 RegisterClass(&WndClass); 33 hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL); 34 ShowWindow(hwnd, nShow); 35 UpdateWindow(hwnd); 36 37 while (GetMessage(&msg, NULL, 0, 0)) 38 { 39 TranslateMessage(&msg); 40 DispatchMessage(&msg); 41 } 42 return 0; 43 } 44 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 45 { 46 HDC hdc; 47 PAINTSTRUCT pt; 48 static TCHAR str[1024] = { 0 }; 49 switch (message) 50 { 51 case WM_CREATE: 52 SetTimer(hwnd, 1, SECOND, TimerProc); 53 SetTimer(hwnd, 2, MINUTE, TimerProc); 54 SetTimer(hwnd, 3, HOUR, TimerProc); 55 second = 0; 56 minute = 0; 57 hour = 0; 58 return 0; 59 case WM_SIZE: 60 return 0; 61 case WM_PAINT: 62 hdc = BeginPaint(hwnd, &pt); 63 Rectangle(hdc, 10, 10, 100, 30); 64 _stprintf(str, TEXT("%d:%d:%d"),hour, minute, second); 65 TextOut(hdc, 13, 11, str, _tcslen(str)); 66 EndPaint(hwnd, &pt); 67 return 0; 68 case WM_DESTROY: 69 KillTimer(hwnd, 1); 70 KillTimer(hwnd, 2); 71 KillTimer(hwnd, 3); 72 PostQuitMessage(0); 73 return 0; 74 default: 75 break; 76 } 77 78 return DefWindowProc(hwnd, message, wParam, lParam); 79 } 80 81 VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) 82 { 83 if (idEvent == 1) 84 { 85 second++; 86 second = second >= 60 ? 0 : second; 87 } 88 else if (idEvent == 2) 89 { 90 minute++; 91 minute = minute >= 60 ? 0 : minute; 92 } 93 else 94 hour++; 95 InvalidateRect(hWnd, NULL, TRUE); 96 }