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消息到應用程序。我們來看一個程序來理解這個用法:
- #include <windows.h>
- #include <mmsystem.h>
- LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- static TCHAR szAppName[] = TEXT ("HelloWin") ;
- HWND hwnd ;
- MSG msg ;
- WNDCLASS wndclass ;
- wndclass.style = CS_HREDRAW | CS_VREDRAW ;
- wndclass.lpfnWndProc = WndProc ;
- wndclass.cbClsExtra = 0 ;
- wndclass.cbWndExtra = 0 ;
- wndclass.hInstance = hInstance ;
- wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
- wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
- wndclass.lpszMenuName = NULL ;
- wndclass.lpszClassName= szAppName ;
- if (!RegisterClass (&wndclass))
- {
- MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
- szAppName, MB_ICONERROR) ;
- return 0 ;
- }
- hwnd = CreateWindow( szAppName, // window class name
- TEXT ("The Hello Program"), // window caption
- WS_OVERLAPPEDWINDOW, // window style
- CW_USEDEFAULT,// initial x position
- CW_USEDEFAULT,// initial y position
- CW_USEDEFAULT,// initial x size
- CW_USEDEFAULT,// initial y size
- NULL, // parent window handle
- NULL, // window menu handle
- hInstance, // program instance handle
- NULL) ; // creation parameters
- ShowWindow (hwnd, iCmdShow) ;
- UpdateWindow (hwnd) ;
- while (GetMessage (&msg, NULL, 0, 0))
- {
- TranslateMessage (&msg) ;
- DispatchMessage (&msg) ;
- }
- return msg.wParam ;
- }
- LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc ;
- static bool flag = false;
- HBRUSH brush;
- PAINTSTRUCT ps ;
- RECT rect ;
- switch (message)
- {
- case WM_CREATE:
- SetTimer(hwnd,1,1000,NULL);
- return 0 ;
- case WM_PAINT:
- hdc = BeginPaint (hwnd, &ps) ;
- GetClientRect(hwnd,&rect);
- FillRect(hdc,&rect,CreateSolidBrush(RGB(255,0,0)));
- EndPaint (hwnd, &ps) ;
- DeleteObject(brush);
- return 0 ;
- case WM_TIMER:
- flag = !flag;
- hdc = GetDC(hwnd);
- GetClientRect(hwnd,&rect);
- brush = CreateSolidBrush(flag?RGB(0,0,255):RGB(255,0,0));
- FillRect(hdc,&rect,brush);
- ReleaseDC(hwnd,hdc);
- DeleteObject(brush);
- return 0;
- case WM_DESTROY:
- KillTimer(hwnd,1);
- PostQuitMessage (0) ;
- return 0 ;
- }
- return DefWindowProc (hwnd, message, wParam, lParam) ;
- }
本程序的用途是設計一個定時器,讓窗口根據定時器來改變窗口的背景顏色.
這裏的知識點有:
① 我們都知道我們要想做些初始化的工作可以在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消息給窗口。然後來執行相應的操作。對於本題來看另外一種方法:
- #include <windows.h>
- #include <mmsystem.h>
- LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- static TCHAR szAppName[] = TEXT ("HelloWin") ;
- HWND hwnd ;
- MSG msg ;
- WNDCLASS wndclass ;
- wndclass.style = CS_HREDRAW | CS_VREDRAW ;
- wndclass.lpfnWndProc = WndProc ;
- wndclass.cbClsExtra = 0 ;
- wndclass.cbWndExtra = 0 ;
- wndclass.hInstance = hInstance ;
- wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
- wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
- wndclass.lpszMenuName = NULL ;
- wndclass.lpszClassName= szAppName ;
- if (!RegisterClass (&wndclass))
- {
- MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
- szAppName, MB_ICONERROR) ;
- return 0 ;
- }
- hwnd = CreateWindow( szAppName, // window class name
- TEXT ("The Hello Program"), // window caption
- WS_OVERLAPPEDWINDOW, // window style
- CW_USEDEFAULT,// initial x position
- CW_USEDEFAULT,// initial y position
- CW_USEDEFAULT,// initial x size
- CW_USEDEFAULT,// initial y size
- NULL, // parent window handle
- NULL, // window menu handle
- hInstance, // program instance handle
- NULL) ; // creation parameters
- ShowWindow (hwnd, iCmdShow) ;
- UpdateWindow (hwnd) ;
- while (GetMessage (&msg, NULL, 0, 0))
- {
- TranslateMessage (&msg) ;
- DispatchMessage (&msg) ;
- }
- return msg.wParam ;
- }
- LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc ;
- static bool flag = false;
- HBRUSH brush;
- PAINTSTRUCT ps ;
- RECT rect ;
- switch (message)
- {
- case WM_CREATE:
- SetTimer(hwnd,1,1000,NULL);
- return 0 ;
- case WM_PAINT:
- hdc = BeginPaint (hwnd, &ps) ;
- GetClientRect(hwnd,&rect);
- brush = CreateSolidBrush(flag?RGB(0,0,255):RGB(255,0,0));
- FillRect(hdc,&rect,brush);
- EndPaint (hwnd, &ps) ;
- DeleteObject(brush);
- return 0 ;
- case WM_TIMER:
- flag = !flag;
- InvalidateRect(hwnd,NULL,FALSE);
- return 0;
- case WM_DESTROY:
- KillTimer(hwnd,1);
- PostQuitMessage (0) ;
- return 0 ;
- }
- return DefWindowProc (hwnd, message, wParam, lParam) ;
- }
該方法裏使用了函數
BOOL InvalidateRect( HWND hWnd, const RECT *lpRect, BOOL bErase );第一個參數爲窗口句柄。但本參數爲NULL時,操作系統將會使整個窗口無效並重劃整個窗口,並在函數返回前發送WM_ERASEBKGND消息給窗口函數。
第二個參數爲將要更新的座標區域。若此參數爲NULL,整個客戶區將會被更新。即發送WM_PAINT消息。
第三個參數是一個bool類型。如果爲true,背景將會在BeginPaint調用時被擦除。若爲false將不會被擦除。