Win32 计时器消息 - WM_TIMER,SetTimer

注:以下内容为学习笔记,多数是从书本、资料中得来,只为加深印象,及日后参考。然而本人表达能力较差,写的不好。因非翻译、非转载,只好选原创,但多数乃摘抄,实为惭愧。但若能帮助一二访客,幸甚!


以下内容多数来自于《Windows程序设计》

1.计时器基础

Windows计时器是一种输入设备,每到一个指定的时间间隔,它都会周期性地发送WM_TIMER通知应用程序。

一些应用:多任务、保持更新进度报告(不断显式变化的信息)、实现定期自动存储、终止程序的演示版、控制运动速度、多媒体。

Windows应用程序是通过正常的消息队列来接收WM_TIMER消息,所以不用担心程序在处理其他任务时会被突然而来的WM_TIMER消息所“中断”。

WM_TIMER消息被放在正常的消息队列中,并和其他消息一起排队等候处理。因此并不能保证每隔指定时间就收到一个WM_TIMER消息。

WM_TIMER和WM_PAINT消息类似,都是低优先级的,只有当消息队列中没有其他消息时,程序才会收到它们。同样,应用程序也同时不会收到大量的WM_TIMER消息。因此不能通过WM_TIMER消息数来判定过去了多长时间。


2.使用计时器的方法

1)法1:

[cpp]  view plain  copy
 print ?
  1. SetTimer(hwnd, 1, uiMsecInterval, NULL);  
  2. KillTimer(hwnd, 1);  

在 WM_TIMER消息中,wParam等于计时器的ID。

[cpp]  view plain  copy
 print ?
  1. /*-------------------------------------- 
  2.    BEEPER1.C -- Timer Demo Program ver1 
  3. --------------------------------------*/  
  4.   
  5. #include <windows.h>  
  6. #include <stdlib.h>  
  7.   
  8. #define ID_TIMER    1  
  9.   
  10. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  11.   
  12. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  
  13.                     PSTR szCmdLine, int iCmdShow)  
  14. {  
  15.     static TCHAR szAppName[] = TEXT("Beeper1");  
  16.     HWND         hwnd;  
  17.     MSG          msg;  
  18.     WNDCLASS     wndclass;  
  19.   
  20.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;  
  21.     wndclass.lpfnWndProc   = WndProc;  
  22.     wndclass.cbClsExtra    = 0;  
  23.     wndclass.cbWndExtra    = 0;  
  24.     wndclass.hInstance     = hInstance;  
  25.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  
  26.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);  
  27.     wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);  
  28.     wndclass.lpszMenuName  = NULL;  
  29.     wndclass.lpszClassName = szAppName;  
  30.   
  31.     if (!RegisterClass (&wndclass))  
  32.     {  
  33.     MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);  
  34.     return 0 ;  
  35.     }  
  36.   
  37.     hwnd = CreateWindow(szAppName, TEXT ("Beeper1 Timer Demo"),  
  38.                         WS_OVERLAPPEDWINDOW,  
  39.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  40.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  41.                         NULL, NULL, hInstance, NULL);  
  42.   
  43.     ShowWindow(hwnd, iCmdShow);  
  44.     UpdateWindow(hwnd);  
  45.   
  46.     while (GetMessage(&msg, NULL, 0, 0))  
  47.     {  
  48.         TranslateMessage(&msg);  
  49.         DispatchMessage(&msg);  
  50.     }  
  51.     return msg.wParam;  
  52. }  
  53.   
  54. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  55. {  
  56.     HBRUSH          hBrush;  
  57.     HDC             hdc;  
  58.     PAINTSTRUCT     ps;  
  59.     RECT            rc;  
  60.   
  61.     switch (message)  
  62.     {  
  63.     case WM_CREATE:  
  64.         SetTimer(hwnd, ID_TIMER, 1000, NULL);  
  65.         return 0 ;  
  66.   
  67.     case WM_TIMER:  
  68.         MessageBeep(-1);  
  69.         InvalidateRect(hwnd, NULL, FALSE);  
  70.         return 0;  
  71.   
  72.     case WM_PAINT:  
  73.         hdc = BeginPaint (hwnd, &ps) ;  
  74.   
  75.         GetClientRect(hwnd, &rc);  
  76.         hBrush = CreateSolidBrush(RGB(rand()%255, rand()%255, rand()%255));  
  77.         FillRect(hdc, &rc, hBrush);  
  78.   
  79.         EndPaint (hwnd, &ps) ;  
  80.         return 0 ;  
  81.   
  82.     case WM_DESTROY:  
  83.         KillTimer(hwnd, ID_TIMER);  
  84.         PostQuitMessage (0) ;  
  85.         return 0 ;  
  86.     }  
  87.     return DefWindowProc (hwnd, message, wParam, lParam) ;  
  88. }  



2)法2:

让Windows把计时器消息发送到程序中的另一个函数。

收到计时器消息的函数被称为“回调”函数。这是程序中被Windows调用的函数。回调函数必须定义为CALLBACK类型,因为Windows是从程序的代码空间以外调用这个函数的。送到回调函数的参数和从回调函数返回的数据是由该函数要实现的功能所决定的。当回调函数与计时器同时使用时,它的参数实际上与窗口过程的参数是一样的,只不过他们的定义不同。

[cpp]  view plain  copy
 print ?
  1.   
[cpp]  view plain  copy
 print ?
  1. VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)  
  2. {  
  3. }   
  4.   
  5. SetTimer(hwnd, iTimerID, iMsecInterval, TimerProc);  
示例:

[cpp]  view plain  copy
 print ?
  1. /*----------------------------------------------------------- 
  2.    BEEPER2.cpp -- Timer Demo Program ver1 
  3. ------------------------------------------------------------*/  
  4.   
  5. #include <windows.h>  
  6. #include <stdlib.h>  
  7.   
  8. #define ID_TIMER    1  
  9.   
  10. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  11. VOID    CALLBACK TimerProc(HWNDUINTUINTDWORD);  
  12.   
  13. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  
  14.                     PSTR szCmdLine, int iCmdShow)  
  15. {  
  16.     static TCHAR szAppName[] = TEXT("Beeper2");  
  17.     HWND         hwnd;  
  18.     MSG          msg;  
  19.     WNDCLASS     wndclass;  
  20.   
  21.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;  
  22.     wndclass.lpfnWndProc   = WndProc;  
  23.     wndclass.cbClsExtra    = 0;  
  24.     wndclass.cbWndExtra    = 0;  
  25.     wndclass.hInstance     = hInstance;  
  26.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  
  27.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);  
  28.     wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);  
  29.     wndclass.lpszMenuName  = NULL;  
  30.     wndclass.lpszClassName = szAppName;  
  31.   
  32.     if (!RegisterClass (&wndclass))  
  33.     {  
  34.     MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);  
  35.     return 0 ;  
  36.     }  
  37.   
  38.     hwnd = CreateWindow(szAppName, TEXT ("Beeper2 Timer Demo"),  
  39.                         WS_OVERLAPPEDWINDOW,  
  40.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  41.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  42.                         NULL, NULL, hInstance, NULL);  
  43.   
  44.     ShowWindow(hwnd, iCmdShow);  
  45.     UpdateWindow(hwnd);  
  46.   
  47.     while (GetMessage(&msg, NULL, 0, 0))  
  48.     {  
  49.         TranslateMessage(&msg);  
  50.         DispatchMessage(&msg);  
  51.     }  
  52.     return msg.wParam;  
  53. }  
  54.   
  55. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  56. {  
  57.     switch (message)  
  58.     {  
  59.     case WM_CREATE:  
  60.         SetTimer(hwnd, ID_TIMER, 1000, TimerProc);  
  61.         return 0 ;  
  62.   
  63.     case WM_DESTROY:  
  64.         KillTimer(hwnd, ID_TIMER);  
  65.         PostQuitMessage (0) ;  
  66.         return 0 ;  
  67.     }  
  68.     return DefWindowProc (hwnd, message, wParam, lParam) ;  
  69. }  
  70.   
  71. VOID CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)  
  72. {  
  73.     HBRUSH          hBrush;  
  74.     HDC             hdc;  
  75.     RECT            rc;  
  76.   
  77.     MessageBeep(-1);  
  78.   
  79.     GetClientRect(hwnd, &rc);  
  80.   
  81.     hdc     = GetDC(hwnd);  
  82.     hBrush = CreateSolidBrush(RGB(rand()%255, rand()%255, rand()%255));  
  83.     FillRect(hdc, &rc, hBrush);  
  84.     ReleaseDC(hwnd, hdc);  
  85.     DeleteObject(hBrush);  
  86. }  

3)法3:

需要多次调用SetTimer,又不想记录哪些计时器ID已经被使用过,可以:

[cpp]  view plain  copy
 print ?
  1. iTimerID = SetTimer(NULL, 0, wMsecInterval, TimerProc);  
  2. KillTimer(NULL, iTimerID);  


3.使用计时器作为时钟

1)数字时钟

模拟LED的七段显示,显示当前时间:
[cpp]  view plain  copy
 print ?
  1. /*----------------------------------------------------------- 
  2.    digClock.cpp -- Digital Clock 
  3. ------------------------------------------------------------*/  
  4.   
  5. #include <windows.h>  
  6.   
  7. #define ID_TIMER    1  
  8.   
  9. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  10.   
  11. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  
  12.                     PSTR szCmdLine, int iCmdShow)  
  13. {  
  14.     static TCHAR szAppName[] = TEXT("DigClock");  
  15.     HWND         hwnd;  
  16.     MSG          msg;  
  17.     WNDCLASS     wndclass;  
  18.   
  19.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;  
  20.     wndclass.lpfnWndProc   = WndProc;  
  21.     wndclass.cbClsExtra    = 0;  
  22.     wndclass.cbWndExtra    = 0;  
  23.     wndclass.hInstance     = hInstance;  
  24.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  
  25.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);  
  26.     wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);  
  27.     wndclass.lpszMenuName  = NULL;  
  28.     wndclass.lpszClassName = szAppName;  
  29.   
  30.     if (!RegisterClass (&wndclass))  
  31.     {  
  32.     MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);  
  33.     return 0 ;  
  34.     }  
  35.   
  36.     hwnd = CreateWindow(szAppName, TEXT ("Digital Clock"),  
  37.                         WS_OVERLAPPEDWINDOW,  
  38.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  39.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  40.                         NULL, NULL, hInstance, NULL);  
  41.   
  42.     ShowWindow(hwnd, iCmdShow);  
  43.     UpdateWindow(hwnd);  
  44.   
  45.     while (GetMessage(&msg, NULL, 0, 0))  
  46.     {  
  47.         TranslateMessage(&msg);  
  48.         DispatchMessage(&msg);  
  49.     }  
  50.     return msg.wParam;  
  51. }  
  52.   
  53. void DisplayDigit(HDC hdc, int iNumber)  
  54. {  
  55.     static BOOL fSevenSegment[10][7] = {  
  56.         1, 1, 1, 0, 1, 1, 1,     // 0  
  57.         0, 0, 1, 0, 0, 1, 0,     // 1  
  58.         1, 0, 1, 1, 1, 0, 1,     // 2  
  59.         1, 0, 1, 1, 0, 1, 1,     // 3  
  60.         0, 1, 1, 1, 0, 1, 0,     // 4  
  61.         1, 1, 0, 1, 0, 1, 1,     // 5  
  62.         1, 1, 0, 1, 1, 1, 1,     // 6  
  63.         1, 0, 1, 0, 0, 1, 0,     // 7  
  64.         1, 1, 1, 1, 1, 1, 1,     // 8  
  65.         1, 1, 1, 1, 0, 1, 1      // 9  
  66.     };  
  67.   
  68.     static POINT ptSegment [7][6] = {  
  69.         7,  6,  11,  2,  31,  2,  35,  6,  31, 10,  11, 10,  
  70.         6,  7,  10, 11,  10, 31,   6, 35,   2, 31,   2, 11,  
  71.        36,  7,  40, 11,  40, 31,  36, 35,  32, 31,  32, 11,  
  72.         7, 36,  11, 32,  31, 32,  35, 36,  31, 40,  11, 40,  
  73.         6, 37,  10, 41,  10, 61,   6, 65,   2, 61,   2, 41,  
  74.        36, 37,  40, 41,  40, 61,  36, 65,  32, 61,  32, 41,  
  75.         7, 66,  11, 62,  31, 62,  35, 66,  31, 70,  11, 70   
  76.     };  
  77.       
  78.     int          iSeg;  
  79.   
  80.     for (iSeg = 0; iSeg < 7; iSeg++)  
  81.         if (fSevenSegment[iNumber][iSeg])  
  82.             Polygon(hdc, ptSegment[iSeg], 6);  
  83. }  
  84.   
  85. void DisplayTwoDigits(HDC hdc, int iNumber, BOOL fSuppress)  
  86. {  
  87.     //if (!fSuppress || (iNumber / 10 != 0))  
  88.     DisplayDigit(hdc, iNumber / 10);  
  89.     OffsetWindowOrgEx(hdc, -42, 0, NULL);  
  90.       
  91.     DisplayDigit(hdc, iNumber % 10);  
  92.     OffsetWindowOrgEx(hdc, -42, 0, NULL);  
  93. }  
  94.   
  95. void DisplayColon(HDC hdc)  
  96. {  
  97.     POINT ptColon[2][4] = { 2,  21,  6,  17,  10, 21,  6, 25,  
  98.                             2,  51,  6,  47,  10, 51,  6, 55 };  
  99.   
  100.     Polygon(hdc, ptColon[0], 4);  
  101.     Polygon(hdc, ptColon[1], 4);  
  102.   
  103.     OffsetWindowOrgEx(hdc, -12, 0, NULL);  
  104. }  
  105.   
  106. void DisplayTime(HDC hdc, BOOL f24Hour, BOOL fSuppress)  
  107. {  
  108.     SYSTEMTIME st;  
  109.   
  110.     GetLocalTime(&st);  
  111.   
  112.     if (f24Hour)  
  113.         DisplayTwoDigits(hdc, st.wHour, fSuppress);  
  114.     else  
  115.         DisplayTwoDigits(hdc, (st.wHour %= 12) ? st.wHour : 12, fSuppress);  
  116.   
  117.     DisplayColon(hdc);  
  118.     DisplayTwoDigits(hdc, st.wMinute, fSuppress);  
  119.     DisplayColon(hdc);  
  120.     DisplayTwoDigits(hdc, st.wSecond, fSuppress);  
  121. }  
  122.   
  123. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  124. {  
  125.     static BOOL     f24Hour, fSuppress;  
  126.     static HBRUSH   hBrushRed;  
  127.     static int      cxClient, cyClient;  
  128.     HDC             hdc;  
  129.     PAINTSTRUCT     ps;  
  130.     TCHAR           szBuffer[2];  
  131.   
  132.     switch (message)  
  133.     {  
  134.     case WM_CREATE:  
  135.         hBrushRed = CreateSolidBrush(RGB(255, 0, 0));  
  136.         SetTimer(hwnd, ID_TIMER, 1000, NULL);  
  137.           
  138.         // fall through  
  139.   
  140.     case WM_SETTINGCHANGE:  
  141.         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, szBuffer, 2);  
  142.         f24Hour = (szBuffer[0] == '1');  
  143.   
  144.         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITLZERO, szBuffer, 2);  
  145.         fSuppress = (szBuffer[0] == '0');  
  146.   
  147.         InvalidateRect(hwnd, NULL, TRUE);  
  148.         return 0;  
  149.   
  150.     case WM_SIZE:  
  151.         cxClient = LOWORD(lParam);  
  152.         cyClient = HIWORD(lParam);  
  153.         return 0;  
  154.   
  155.     case WM_TIMER:  
  156.         InvalidateRect(hwnd, NULL, TRUE);  
  157.         return 0;  
  158.   
  159.     case WM_PAINT:  
  160.         hdc = BeginPaint(hwnd, &ps);  
  161.   
  162.         SetMapMode(hdc, MM_ISOTROPIC);  
  163.         SetWindowExtEx(hdc, 276, 72, NULL);  
  164.         SetViewportExtEx(hdc, cxClient, cyClient, NULL);  
  165.   
  166.         SetWindowExtEx(hdc, 138, 36, NULL);  
  167.         SetViewportExtEx(hdc, cxClient/2, cyClient/2, NULL);  
  168.   
  169.         SelectObject(hdc, GetStockObject(NULL_PEN));  
  170.         SelectObject(hdc, hBrushRed);  
  171.   
  172.         DisplayTime(hdc, f24Hour, fSuppress);  
  173.   
  174.         EndPaint(hwnd, &ps);  
  175.         return 0;  
  176.   
  177.     case WM_DESTROY:  
  178.         KillTimer(hwnd, ID_TIMER);  
  179.         DeleteObject(hBrushRed);  
  180.         PostQuitMessage (0) ;  
  181.         return 0 ;  
  182.     }  
  183.     return DefWindowProc (hwnd, message, wParam, lParam) ;  
  184. }  



2)模拟时钟

[cpp]  view plain  copy
 print ?
  1. /*----------------------------------------------------------- 
  2.    digClock.cpp -- Digital Clock 
  3. ------------------------------------------------------------*/  
  4.   
  5. #include <windows.h>  
  6. #include <math.h>  
  7.   
  8. #define ID_TIMER    1  
  9. #define TWOPI       (2*3.14159)  
  10.   
  11. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  12.   
  13. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  
  14.                     PSTR szCmdLine, int iCmdShow)  
  15. {  
  16.     static TCHAR szAppName[] = TEXT("DigClock");  
  17.     HWND         hwnd;  
  18.     MSG          msg;  
  19.     WNDCLASS     wndclass;  
  20.   
  21.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;  
  22.     wndclass.lpfnWndProc   = WndProc;  
  23.     wndclass.cbClsExtra    = 0;  
  24.     wndclass.cbWndExtra    = 0;  
  25.     wndclass.hInstance     = hInstance;  
  26.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  
  27.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);  
  28.     wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);  
  29.     wndclass.lpszMenuName  = NULL;  
  30.     wndclass.lpszClassName = szAppName;  
  31.   
  32.     if (!RegisterClass (&wndclass))  
  33.     {  
  34.     MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);  
  35.     return 0 ;  
  36.     }  
  37.   
  38.     hwnd = CreateWindow(szAppName, TEXT ("Digital Clock"),  
  39.                         WS_OVERLAPPEDWINDOW,  
  40.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  41.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  42.                         NULL, NULL, hInstance, NULL);  
  43.   
  44.     ShowWindow(hwnd, iCmdShow);  
  45.     UpdateWindow(hwnd);  
  46.   
  47.     while (GetMessage(&msg, NULL, 0, 0))  
  48.     {  
  49.         TranslateMessage(&msg);  
  50.         DispatchMessage(&msg);  
  51.     }  
  52.     return msg.wParam;  
  53. }  
  54.   
  55.   
  56. void SetIsotropic(HDC hdc, int cxClient, int cyClient)  
  57. {  
  58.     SetMapMode(hdc, MM_ISOTROPIC);  
  59.     SetWindowExtEx(hdc, 1000, 1000, NULL);  
  60.     SetViewportExtEx(hdc, cxClient/2, -cyClient/2, NULL);  
  61.     SetViewportOrgEx(hdc, cxClient/2,  cyClient/2, NULL);  
  62. }  
  63.   
  64.   
  65. void RotatePoint(POINT pt[], int iNum, int iAngle)  
  66. {  
  67.     int         i;  
  68.     POINT       ptTemp;  
  69.   
  70.     for (i = 0; i < iNum; i++)  
  71.     {  
  72.         ptTemp.x = (int)( pt[i].x * cos(TWOPI*iAngle/360) + pt[i].y * sin(TWOPI*iAngle/360) );  
  73.         ptTemp.y = (int)( pt[i].y * cos(TWOPI*iAngle/360) + pt[i].x * sin(TWOPI*iAngle/360) );  
  74.   
  75.         pt[i] = ptTemp;  
  76.     }  
  77. }  
  78.   
  79. void DrawClock(HDC hdc)  
  80. {  
  81.     int     iAngle;  
  82.     POINT   pt[3];  
  83.   
  84.     for (iAngle = 0; iAngle < 360; iAngle += 6)  
  85.     {  
  86.         pt[0].x = 0;  
  87.         pt[0].y = 900;  
  88.   
  89.         RotatePoint(pt, 1, iAngle);  
  90.   
  91.         pt[2].x = pt[2].y = iAngle%5 ? 33 : 100;  
  92.   
  93.         pt[0].x -= pt[2].x / 2;  
  94.         pt[0].y -= pt[2].y / 2;  
  95.   
  96.         pt[1].x = pt[0].x + pt[2].x;  
  97.         pt[1].y = pt[0].y + pt[2].y;  
  98.   
  99.         SelectObject(hdc, GetStockObject(BLACK_BRUSH));  
  100.   
  101.         Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);  
  102.     }  
  103. }  
  104.   
  105.   
  106. void DrawHands(HDC hdc, SYSTEMTIME* pst, BOOL fChange)  
  107. {  
  108.     static POINT pt[3][5] = {   
  109.         0, -150, 100, 0, 0, 600, -100, 0, 0, -150,  
  110.         0, -200,  50, 0, 0, 800,  -50, 0, 0, -200,  
  111.         0,    0,   0, 0, 0,   0,    0, 0, 0,  800   
  112.     };  
  113.   
  114.     int         i, iAngle[3];  
  115.     POINT       ptTemp[3][5];  
  116.   
  117.     iAngle[0] = (pst->wHour * 30) % 360 + pst->wMinute/2;  
  118.     iAngle[1] = pst->wMinute * 6;  
  119.     iAngle[2] = pst->wSecond * 6;  
  120.   
  121.     memcpy(ptTemp, pt, sizeof(pt));  
  122.   
  123.     for (i = fChange ? 0 : 2; i < 3; i++)  
  124.     {  
  125.         RotatePoint(ptTemp[i], 5, iAngle[i]);  
  126.   
  127.         Polyline(hdc, ptTemp[i], 5);  
  128.     }  
  129. }  
  130.   
  131.   
  132. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  133. {  
  134.     static SYSTEMTIME   stPrevious;  
  135.     static int          cxClient, cyClient;  
  136.     BOOL                fChange;  
  137.     HDC                 hdc;  
  138.     PAINTSTRUCT         ps;  
  139.     SYSTEMTIME          st;  
  140.   
  141.     switch (message)  
  142.     {  
  143.     case WM_CREATE:  
  144.         SetTimer(hwnd, ID_TIMER, 1000, NULL);  
  145.         GetLocalTime(&st);  
  146.         stPrevious = st;  
  147.         return 0;  
  148.   
  149.     case WM_SIZE:  
  150.         cxClient = LOWORD(lParam);  
  151.         cyClient = HIWORD(lParam);  
  152.         return 0;  
  153.   
  154.     case WM_TIMER:  
  155.         GetLocalTime(&st);  
  156.         fChange = st.wHour != stPrevious.wHour ||   
  157.             st.wMinute  != stPrevious.wHour;  
  158.   
  159.         hdc = GetDC(hwnd);  
  160.         SetIsotropic(hdc, cxClient, cyClient);  
  161.   
  162.         SelectObject(hdc, GetStockObject(WHITE_PEN));  
  163.         DrawHands(hdc, &stPrevious, fChange);  
  164.   
  165.         SelectObject(hdc, GetStockObject(BLACK_PEN));  
  166.         DrawHands(hdc, &st, TRUE);  
  167.           
  168.         ReleaseDC(hwnd, hdc);  
  169.         stPrevious = st;  
  170.           
  171.         return 0;  
  172.   
  173.     case WM_PAINT:  
  174.         hdc = BeginPaint(hwnd, &ps);  
  175.   
  176.         SetIsotropic(hdc, cxClient, cyClient);  
  177.         DrawClock(hdc);  
  178.         DrawHands(hdc, &stPrevious, TRUE);  
  179.   
  180.         EndPaint(hwnd, &ps);  
  181.         return 0;  
  182.   
  183.     case WM_DESTROY:  
  184.         KillTimer(hwnd, ID_TIMER);  
  185.         PostQuitMessage (0) ;  
  186.         return 0 ;  
  187.     }  
  188.     return DefWindowProc (hwnd, message, wParam, lParam) ;  
  189. }  



4.在状态报告中使用计时器

[cpp]  view plain  copy
 print ?
  1. /*----------------------------------------------------------- 
  2.    whatclr.cpp -- Displays Color Under Cursor 
  3. ------------------------------------------------------------*/  
  4.   
  5. #include <windows.h>  
  6.   
  7. #define ID_TIMER    1  
  8.   
  9. void FindWindowSize(int* , int* );  
  10. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  11.   
  12. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  
  13.                     PSTR szCmdLine, int iCmdShow)  
  14. {  
  15.     static TCHAR szAppName[] = TEXT("WhatClr");  
  16.     HWND         hwnd;  
  17.     MSG          msg;  
  18.     WNDCLASS     wndclass;  
  19.   
  20.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;  
  21.     wndclass.lpfnWndProc   = WndProc;  
  22.     wndclass.cbClsExtra    = 0;  
  23.     wndclass.cbWndExtra    = 0;  
  24.     wndclass.hInstance     = hInstance;  
  25.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  
  26.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);  
  27.     wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);  
  28.     wndclass.lpszMenuName  = NULL;  
  29.     wndclass.lpszClassName = szAppName;  
  30.   
  31.     if (!RegisterClass (&wndclass))  
  32.     {  
  33.     MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);  
  34.     return 0 ;  
  35.     }  
  36.   
  37.     hwnd = CreateWindow(szAppName, TEXT ("What Color"),  
  38.                         WS_OVERLAPPEDWINDOW,  
  39.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  40.                         CW_USEDEFAULT, CW_USEDEFAULT,  
  41.                         NULL, NULL, hInstance, NULL);  
  42.   
  43.     ShowWindow(hwnd, iCmdShow);  
  44.     UpdateWindow(hwnd);  
  45.   
  46.     while (GetMessage(&msg, NULL, 0, 0))  
  47.     {  
  48.         TranslateMessage(&msg);  
  49.         DispatchMessage(&msg);  
  50.     }  
  51.     return msg.wParam;  
  52. }  
  53.   
  54.   
  55. void FindWindowSize(int* pcxWindow, int* pcyWindow)  
  56. {  
  57.     HDC         hdcScreen;  
  58.     TEXTMETRIC  tm;  
  59.   
  60.     hdcScreen = CreateIC(TEXT("DISPLAY"), NULL, NULL, NULL);  
  61.     GetTextMetrics(hdcScreen, &tm);  
  62.     DeleteDC(hdcScreen);  
  63.   
  64.     *pcxWindow = 2 * GetSystemMetrics(SM_CXBORDER) + 12 * tm.tmAveCharWidth;  
  65.     *pcyWindow = 2 * GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYCAPTION) + 2 * tm.tmHeight;  
  66. }  
  67.   
  68.   
  69. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  70. {  
  71.     static COLORREF     cr, crLast;  
  72.     static HDC          hdcScreen;  
  73.     HDC                 hdc;  
  74.     PAINTSTRUCT         ps;  
  75.     POINT               pt;  
  76.     RECT                rc;  
  77.     TCHAR               szBuffer[16];  
  78.   
  79.     switch (message)  
  80.     {  
  81.     case WM_CREATE:  
  82.         hdcScreen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);  
  83.   
  84.         SetTimer(hwnd, ID_TIMER, 100, NULL);  
  85.         return 0;  
  86.   
  87.     case WM_TIMER:  
  88.         GetCursorPos(&pt);  
  89.         cr = GetPixel(hdcScreen, pt.x, pt.y);  
  90.   
  91.         SetPixel(hdcScreen, pt.x, pt.y, 0);  
  92.   
  93.         if (cr != crLast)  
  94.         {  
  95.             crLast = cr;  
  96.             InvalidateRect(hwnd, NULL, FALSE);  
  97.         }  
  98.           
  99.         return 0;  
  100.   
  101.     case WM_PAINT:  
  102.         hdc = BeginPaint(hwnd, &ps);  
  103.   
  104.         GetClientRect(hwnd, &rc);  
  105.   
  106.         wsprintf(szBuffer, TEXT("   %02X %02X %02X   "), GetRValue(cr), GetGValue(cr), GetBValue(cr));  
  107.   
  108.         DrawText(hdc, szBuffer, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);  
  109.   
  110.         EndPaint(hwnd, &ps);  
  111.         return 0;  
  112.   
  113.     case WM_DESTROY:  
  114.         DeleteDC(hdcScreen);  
  115.         KillTimer(hwnd, ID_TIMER);  
  116.         PostQuitMessage (0);  
  117.         return 0;  
  118.     }  
  119.     return DefWindowProc (hwnd, message, wParam, lParam);  
  120. }  
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,可以使用Windows API中的SetTimer函数来创建一个计时器,该函数的原型如下: ``` UINT_PTR SetTimer( HWND hWnd, // 窗口句柄 UINT_PTR nIDEvent, // 计时器标识符 UINT uElapse, // 计时间隔,单位为毫秒 TIMERPROC lpTimerFunc// 计时器回调函数 ); ``` 其中,hWnd参数是要接收计时器消息的窗口句柄,nIDEvent是计时器的标识符,可以用于取消计时器,uElapse是计时间隔,单位是毫秒,lpTimerFunc是计时器回调函数,当计时器到达指定时间时,系统会发送一个WM_TIMER消息给指定窗口,同时调用回调函数。 以下是一个简单的示例代码,实现了每秒钟在窗口标题中显示当前时间: ```c++ #include <Windows.h> #include <string> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: // 创建一个每秒钟触发一次的计时器 SetTimer(hWnd, 1, 1000, NULL); break; case WM_TIMER: if (wParam == 1) { // 获取当前时间 SYSTEMTIME st; GetLocalTime(&st); std::wstring title = L"Current Time: "; title += std::to_wstring(st.wHour) + L":" + std::to_wstring(st.wMinute) + L":" + std::to_wstring(st.wSecond); // 更新窗口标题 SetWindowText(hWnd, title.c_str()); } break; case WM_DESTROY: // 销毁计时器 KillTimer(hWnd, 1); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // 注册窗口类 WNDCLASS wc = { 0 }; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszClassName = L"TimerDemo"; RegisterClass(&wc); // 创建窗口 HWND hWnd = CreateWindow(L"TimerDemo", L"Timer Demo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } // 显示窗口 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // 消息循环 MSG msg = { 0 }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } ``` 该示例代码中,我们在窗口创建时创建了一个每秒钟触发一次的计时器,并在计时器回调函数中获取当前时间,并将其显示在窗口标题中。在窗口销毁时,我们销毁了计时器

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值