計時器--(一)

1 UINT SetTimer(

HWND hWnd, //窗口句柄

UINT nIDEvent, //計時器ID

UINT uElapse, //時間間隔

TIMERPROC lpTimerFunc );//回調函數

第一個參數:窗口句柄,他表示了調用定時器的窗口,若該參數爲空,則第二個參數將被忽略。

第二個參數:計時器的ID,通過此參數可以標識多個定時器,爲非零值。

第三個參數:時間間隔。以毫秒爲單位。

第四個參數:回調函數。操作系統將在每個我們定義的間隔過去後調用該函數。若該參數爲NULL,操作系統將發送WM_TIMER消息到應用程序的消息隊列中。

回調函數有一定的格式:

void CALLBACK TimerProc(

HWND hwnd, //窗口句柄

UINT uMsg, //消息

UINT idEvent, //定時器ID

DWORD dwTime );//操作系統自開機經過的毫秒數。

計時器的用法:

:

SetTimer(hwnd,1,uiMsecInerval,NULL);

給據上面我門對計時器參數的解釋可知:當最後一個參數爲NULL的時候,操作系統將發送WM_TIMER消息到應用程序。我們來看一個程序來理解這個用法:

Code:
  1. #include <windows.h>   
  2. #include <mmsystem.h>   
  3. LRESULT CALLBACK WndProc (HWNDUINTWPARAMLPARAM) ;   
  4. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,     
  5.                    PSTR szCmdLine, int iCmdShow)   
  6.            
  7. {   
  8.     static TCHAR szAppName[] = TEXT ("HelloWin") ;   
  9.     HWND   hwnd ;       
  10.     MSG    msg ;          
  11.     WNDCLASS wndclass ;   
  12.     wndclass.style        = CS_HREDRAW | CS_VREDRAW ;       
  13.     wndclass.lpfnWndProc  = WndProc ;     
  14.     wndclass.cbClsExtra   = 0 ;          
  15.     wndclass.cbWndExtra   = 0 ;          
  16.     wndclass.hInstance    = hInstance ;   
  17.     wndclass.hIcon        = LoadIcon (NULL, IDI_APPLICATION) ;          
  18.     wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW) ;           
  19.     wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;          
  20.     wndclass.lpszMenuName  = NULL ;          
  21.     wndclass.lpszClassName= szAppName ;           
  22.     if (!RegisterClass (&wndclass))           
  23.     {         
  24.             MessageBox (  NULL, TEXT ("This program requires Windows NT!"),          
  25.                                   szAppName, MB_ICONERROR) ;         
  26.             return 0 ;          
  27.     }         
  28.     hwnd = CreateWindow( szAppName,      // window class name       
  29.                    TEXT ("The Hello Program"),   // window caption        
  30.                    WS_OVERLAPPEDWINDOW,  // window style   
  31.                    CW_USEDEFAULT,// initial x position   
  32.                    CW_USEDEFAULT,// initial y position   
  33.                    CW_USEDEFAULT,// initial x size   
  34.                    CW_USEDEFAULT,// initial y size   
  35.                    NULL,                 // parent window handle   
  36.                    NULL,            // window menu handle   
  37.                    hInstance,   // program instance handle   
  38.                    NULL) ;      // creation parameters      
  39.     ShowWindow (hwnd, iCmdShow) ;      
  40.     UpdateWindow (hwnd) ;     
  41.     while (GetMessage (&msg, NULL, 0, 0))       
  42.     {     
  43.           TranslateMessage (&msg) ;   
  44.           DispatchMessage (&msg) ;       
  45.     }       
  46.     return msg.wParam ;          
  47. }   
  48. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)           
  49. {         
  50.     HDC  hdc ;   
  51.     static bool flag = false;   
  52.     HBRUSH brush;   
  53.     PAINTSTRUCT ps ;    
  54.     RECT rect ;     
  55.     switch (message)       
  56.     {        
  57.     case WM_CREATE:     
  58.             SetTimer(hwnd,1,1000,NULL);   
  59.                
  60.             return 0 ;   
  61.     case   WM_PAINT:   
  62.             hdc = BeginPaint (hwnd, &ps) ;   
  63.             GetClientRect(hwnd,&rect);   
  64.             FillRect(hdc,&rect,CreateSolidBrush(RGB(255,0,0)));   
  65.             EndPaint (hwnd, &ps) ;   
  66.             DeleteObject(brush);   
  67.             return 0 ;      
  68.     case   WM_TIMER:   
  69.            flag = !flag;   
  70.            hdc = GetDC(hwnd);   
  71.            GetClientRect(hwnd,&rect);   
  72.            brush = CreateSolidBrush(flag?RGB(0,0,255):RGB(255,0,0));   
  73.            FillRect(hdc,&rect,brush);   
  74.            ReleaseDC(hwnd,hdc);   
  75.            DeleteObject(brush);   
  76.            return 0;   
  77.     case   WM_DESTROY:   
  78.             KillTimer(hwnd,1);   
  79.             PostQuitMessage (0) ;   
  80.             return 0 ;     
  81.     }        
  82.   return DefWindowProc (hwnd, message, wParam, lParam) ;   
  83.          
  84. }  

本程序的用途是設計一個定時器,讓窗口根據定時器來改變窗口的背景顏色.

這裏的知識點有:

① 我們都知道我們要想做些初始化的工作可以在WM_CREATE消息裏進行。故我們可以在這裏設定我們的定時器。即在窗口創建時我們就爲他設定好定時器。但是這裏千萬別忘了在WM_DESTROY消息中關閉定時器。即:在我們窗口關閉前關閉我們所設定的定時器.

② 得到窗口的客戶區

  我們用BOOL GetClientRect( HWND hWnd, LPRECT lpRect ); 函數來得到窗口的客戶區。

③ 創建畫刷

   我們使用HBRUSH CreateSolidBrush( COLORREF crColor); 函數來創建畫刷。該函數返回一個畫刷句柄。畫刷使用完畢要記得用DeleteObject刪除創建的畫刷。

④ 用畫刷填充制定區域

   我們使用了int FillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr);來填充。

⑤ 這裏涉及到了兩種獲得hdc的方法

   一種爲利用 HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lpPaint);來返回。

    一種是利用HDC GetDC( HWND hWnd);返回。這兩種都可以獲得HDC,不過前一種只能在WM_PAINT消息中使用。這裏需要注意的是,當我們利用BeginPaint得到HDC別忘了調用BOOL EndPaint( HWND hWnd, CONST PAINTSTRUCT *lpPaint ); 來結束繪圖。利用GetDC得到HDC後不要忘了用ReleseDC來釋放HDC.

SetTime(hwnd,1,1000,NULL);這個用法的意思是每隔一定的時間操作系統就發送WM_PAINT消息給窗口。然後來執行相應的操作。對於本題來看另外一種方法:

Code:
  1. #include <windows.h>   
  2. #include <mmsystem.h>   
  3. LRESULT CALLBACK WndProc (HWNDUINTWPARAMLPARAM) ;   
  4. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,     
  5.                    PSTR szCmdLine, int iCmdShow)   
  6.            
  7. {   
  8.     static TCHAR szAppName[] = TEXT ("HelloWin") ;   
  9.     HWND   hwnd ;       
  10.     MSG    msg ;          
  11.     WNDCLASS wndclass ;   
  12.     wndclass.style        = CS_HREDRAW | CS_VREDRAW ;       
  13.     wndclass.lpfnWndProc  = WndProc ;     
  14.     wndclass.cbClsExtra   = 0 ;          
  15.     wndclass.cbWndExtra   = 0 ;          
  16.     wndclass.hInstance    = hInstance ;   
  17.     wndclass.hIcon        = LoadIcon (NULL, IDI_APPLICATION) ;          
  18.     wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW) ;           
  19.     wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;          
  20.     wndclass.lpszMenuName  = NULL ;          
  21.     wndclass.lpszClassName= szAppName ;           
  22.     if (!RegisterClass (&wndclass))           
  23.     {         
  24.             MessageBox (  NULL, TEXT ("This program requires Windows NT!"),          
  25.                                   szAppName, MB_ICONERROR) ;         
  26.             return 0 ;          
  27.     }         
  28.     hwnd = CreateWindow( szAppName,      // window class name       
  29.                    TEXT ("The Hello Program"),   // window caption        
  30.                    WS_OVERLAPPEDWINDOW,  // window style   
  31.                    CW_USEDEFAULT,// initial x position   
  32.                    CW_USEDEFAULT,// initial y position   
  33.                    CW_USEDEFAULT,// initial x size   
  34.                    CW_USEDEFAULT,// initial y size   
  35.                    NULL,                 // parent window handle   
  36.                    NULL,            // window menu handle   
  37.                    hInstance,   // program instance handle   
  38.                    NULL) ;      // creation parameters      
  39.     ShowWindow (hwnd, iCmdShow) ;      
  40.     UpdateWindow (hwnd) ;     
  41.     while (GetMessage (&msg, NULL, 0, 0))       
  42.     {     
  43.           TranslateMessage (&msg) ;   
  44.           DispatchMessage (&msg) ;       
  45.     }       
  46.     return msg.wParam ;          
  47. }   
  48. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)           
  49. {         
  50.     HDC  hdc ;   
  51.     static bool flag = false;   
  52.     HBRUSH brush;   
  53.     PAINTSTRUCT ps ;    
  54.     RECT rect ;     
  55.     switch (message)       
  56.     {        
  57.     case WM_CREATE:     
  58.             SetTimer(hwnd,1,1000,NULL);   
  59.                
  60.             return 0 ;   
  61.     case   WM_PAINT:   
  62.             hdc = BeginPaint (hwnd, &ps) ;   
  63.             GetClientRect(hwnd,&rect);   
  64.             brush = CreateSolidBrush(flag?RGB(0,0,255):RGB(255,0,0));   
  65.             FillRect(hdc,&rect,brush);   
  66.             EndPaint (hwnd, &ps) ;   
  67.             DeleteObject(brush);   
  68.             return 0 ;      
  69.     case   WM_TIMER:   
  70.            flag = !flag;   
  71.            InvalidateRect(hwnd,NULL,FALSE);   
  72.            return 0;   
  73.     case   WM_DESTROY:   
  74.             KillTimer(hwnd,1);   
  75.             PostQuitMessage (0) ;   
  76.             return 0 ;     
  77.     }        
  78.   return DefWindowProc (hwnd, message, wParam, lParam) ;   
  79.          
  80. }  

該方法裏使用了函數

BOOL InvalidateRect( HWND hWnd, const RECT *lpRect, BOOL bErase );

第一個參數爲窗口句柄。但本參數爲NULL時,操作系統將會使整個窗口無效並重劃整個窗口,並在函數返回前發送WM_ERASEBKGND消息給窗口函數。

第二個參數爲將要更新的座標區域。若此參數爲NULL,整個客戶區將會被更新。即發送WM_PAINT消息。

第三個參數是一個bool類型。如果爲true,背景將會在BeginPaint調用時被擦除。若爲false將不會被擦除。

發佈了50 篇原創文章 · 獲贊 1 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章