admin 管理员组

文章数量: 887032

计时器

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 (HWND, UINT, WPARAM, LPARAM) ;   
  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 (HWND, UINT, WPARAM, LPARAM) ;   
  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将不会被擦除。

本文标签: 计时器