Fork me on GitHub

11 Windows编程——定时器

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

实现定时器源码——法二: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 }
View Code

 

posted @ 2018-07-17 15:48  克拉默与矩阵  阅读(1705)  评论(0编辑  收藏  举报