在Visual Basic裡面可以利用Timer控制項來實現定時的功能,在Windows程式設計裡面同樣可以實現定時的功能,
通過啟用定時器的對象就可以實現定時作用。
用一個簡單的Exp來查看定時器的使用:
/* 本執行個體代碼展示定時器的使用——Beeper程式*/#include <windows.h>#define ID_TIMER 1LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){static TCHAR szAppClassName[]=TEXT("Beeper");static TCHAR szAppWndCaption[]=TEXT("Beeper");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.cbClsExtra=0;wndclass.cbWndExtra=0;wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);wndclass.hInstance=hInstance;wndclass.lpfnWndProc=WndProc;wndclass.lpszClassName=szAppClassName;wndclass.lpszMenuName=NULL;wndclass.style=CS_HREDRAW |CS_VREDRAW;if(!RegisterClass(&wndclass)){MessageBox(NULL,"You need WinNT to run this program!","Warning",MB_OK);return 0;}hwnd=CreateWindow(szAppClassName, szAppWndCaption, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, hInstance, NULL);ShowWindow(hwnd,nShowCmd);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){static BOOL fFlipFlop=FALSE;HBRUSH hBrush;HDC hdc;PAINTSTRUCT ps;RECT rc;switch(message){case WM_CREATE:SetTimer(hwnd,ID_TIMER,1000,NULL);/*WINUSERAPI UINT WINAPI SetTimer(HWND hWnd , 使用定時器的視窗的控制代碼 UINT nIDEvent, 定時器的ID號,這個值可以自訂,為unsigned整數 UINT uElapse, 定時器的時間,時基為ms TIMERPROC lpTimerFunc); */return 0;case WM_TIMER:MessageBeep(-1);fFlipFlop=!fFlipFlop;InvalidateRect(hwnd,NULL,FALSE);return 0;case WM_PAINT:hdc=BeginPaint(hwnd,&ps);GetClientRect(hwnd,&rc);hBrush=CreateSolidBrush(fFlipFlop ? RGB(255,0,0):RGB(0,0,255));FillRect(hdc,&rc,hBrush);DeleteObject(hBrush);EndPaint(hwnd,&ps);return 0;case WM_DESTROY:KillTimer(hwnd,ID_TIMER);PostQuitMessage(0);return 0;}return DefWindowProc(hwnd,message,wParam,lParam);}
需要說明的是SetTimer函數:
/*
WINUSERAPI UINT WINAPI
SetTimer(HWND hWnd , 使用定時器的視窗的控制代碼,就是說定時時間到後那個視窗可以收到WM_TIMER訊息
UINT nIDEvent, 定時器的ID號,這個值可以自訂,為unsigned整數
UINT uElapse, 定時器的時間,時基為ms
TIMERPROC lpTimerFunc); 定時器訊息的回呼函數,這個函數唯一的處理定時器的訊息
*/
在處理定時器訊息時,可以在視窗的訊息處理函數完成,同時還可以定義定時器的回呼函數,
如下Exp:
/* 本執行個體代碼展示定時器的使用——Beeper程式*/#include <windows.h>#define ID_TIMER 1LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam);//定義一個與定時器相關的回呼函數void CALLBACK TimerProc(HWND hwnd,UINT message,UINT iTimeID, DWORD dwTime);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){static TCHAR szAppClassName[]=TEXT("Beeper");static TCHAR szAppWndCaption[]=TEXT("Beeper");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.cbClsExtra=0;wndclass.cbWndExtra=0;wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);wndclass.hInstance=hInstance;wndclass.lpfnWndProc=WndProc;wndclass.lpszClassName=szAppClassName;wndclass.lpszMenuName=NULL;wndclass.style=CS_HREDRAW |CS_VREDRAW;if(!RegisterClass(&wndclass)){MessageBox(NULL,"You need WinNT to run this program!","Warning",MB_OK);return 0;}hwnd=CreateWindow(szAppClassName, szAppWndCaption, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, hInstance, NULL);ShowWindow(hwnd,nShowCmd);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){switch(message){case WM_CREATE:SetTimer(hwnd,ID_TIMER,1000,TimerProc);/*WINUSERAPI UINT WINAPI SetTimer(HWND hWnd , 使用定時器的視窗的控制代碼 UINT nIDEvent, 定時器的ID號,這個值可以自訂,為unsigned整數 UINT uElapse, 定時器的時間,時基為ms TIMERPROC lpTimerFunc); 當定義了定時器訊息的回呼函數時,這個值傳遞的是定時器訊息回呼函數的地址 */return 0;case WM_DESTROY:KillTimer(hwnd,ID_TIMER);PostQuitMessage(0);return 0;}return DefWindowProc(hwnd,message,wParam,lParam);}//實現一個與定時器相關的回呼函數void CALLBACK TimerProc(HWND hwnd, //是在呼叫SetTimer時指定的視窗控制代碼UINT message, //windows只把wm_timer訊息發送給定時器訊息處理回呼函數,因此這個值總是wm_timerUINT iTimeID, // 這個值是定時器的IDDWORD dwTime) //這個是與從GetTickCount函數傳回值相容的值,是自windows啟動後所經過的秒數{ static BOOL fFlipFlop=FALSE;HBRUSH hBrush;HDC hdc;RECT rc;MessageBeep(-1);fFlipFlop=!fFlipFlop;GetClientRect(hwnd,&rc); //取得使用者地區的大小資訊hdc=GetDC(hwnd);hBrush=CreateSolidBrush(fFlipFlop ? RGB(255,0,0):RGB(0,0,255)); //建立純色的畫刷函數FillRect(hdc,&rc,hBrush); //利用指定的畫刷來填充矩形地區ReleaseDC(hwnd,hdc);DeleteObject(hBrush); //使用者建立的對象需要刪除}
我們可以利用定時器來實現簡單的動畫螢幕保護裝置程式:
Exp:
/* 本執行個體代碼展示定時器的使用——Clock 程式*/#include <windows.h>#include <winuser.h>#define ID_TIMER 1LRESULT CALLBACK WndProc(HWND hwnd, UINT message,WPARAM wParam, LPARAM lParam);//定義一個與定時器相關的回呼函數void CALLBACK TimerProc(HWND hwnd,UINT message,UINT iTimeID, DWORD dwTime);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){static TCHAR szAppClassName[]=TEXT("Beeper");static TCHAR szAppWndCaption[]=TEXT("Beeper");HWND hwnd;MSG msg;WNDCLASS wndclass;wndclass.cbClsExtra=0;wndclass.cbWndExtra=0;wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);wndclass.hInstance=hInstance;wndclass.lpfnWndProc=WndProc;wndclass.lpszClassName=szAppClassName;wndclass.lpszMenuName=NULL;wndclass.style=CS_HREDRAW |CS_VREDRAW;if(!RegisterClass(&wndclass)){MessageBox(NULL,"You need WinNT to run this program!","Warning",MB_OK);return 0;} hwnd=CreateWindow(szAppClassName, szAppWndCaption, WS_VISIBLE |WS_POPUP, 0, 0, 1366, 768, NULL, NULL, hInstance, NULL);ShowWindow(hwnd,SW_SHOWMAXIMIZED);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){ switch(message){case WM_CREATE:SetTimer(hwnd,ID_TIMER,1000,TimerProc);/*WINUSERAPI UINT WINAPI SetTimer(HWND hWnd , 使用定時器的視窗的控制代碼 UINT nIDEvent, 定時器的ID號,這個值可以自訂,為unsigned整數 UINT uElapse, 定時器的時間,時基為ms TIMERPROC lpTimerFunc); 當定義了定時器訊息的回呼函數時,這個值傳遞的是定時器訊息回呼函數的地址 */return 0;case WM_KEYDOWN:switch(wParam){case VK_ESCAPE:PostQuitMessage(0);break;default:break;}case WM_DESTROY:KillTimer(hwnd,ID_TIMER);PostQuitMessage(0);return 0;}return DefWindowProc(hwnd,message,wParam,lParam);}//實現一個與定時器相關的回呼函數void CALLBACK TimerProc(HWND hwnd, //是在呼叫SetTimer時指定的視窗控制代碼 UINT message, //windows只把wm_timer訊息發送給定時器訊息處理回呼函數,因此這個值總是wm_timer UINT iTimeID, // 這個值是定時器的ID DWORD dwTime) //這個是與從GetTickCount函數傳回值相容的值,是自windows啟動後所經過的秒數{ static BOOL fFlipFlop=FALSE;HBRUSH hBrush;HDC hdc;RECT rc;//MessageBeep(-1);fFlipFlop=!fFlipFlop;GetClientRect(hwnd,&rc); //取得使用者地區的大小資訊hdc=GetDC(hwnd);hBrush=CreateSolidBrush(fFlipFlop ? RGB(255,0,0):RGB(0,0,255)); //建立純色的畫刷函數FillRect(hdc,&rc,hBrush); //利用指定的畫刷來填充矩形地區ReleaseDC(hwnd,hdc);DeleteObject(hBrush); //使用者建立的對象需要刪除}
定時器的使用相對來說教容易,主要是理解定時器回呼函數的HWND和SetTiemr函數中的回呼函數地址之間的聯絡,和
視窗控制代碼的對應關係。
定時器的使用要根據實際情況來應用,不能使用太多和定時時間太短的定時器,否則會是系統的效能明顯下降;同時還必須
注意的是,必須在應用程式退出的時候調用KillTimer函數來取消設定的定時器。
如果一個定時器不需要在使用也最好用KillTimer函數來取消定時器。