周期性的发送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 }