在Visual Basic里面可以利用Timer控件来实现定时的功能,在Windows程序设计里面同样可以实现定时的功能,
通过启用定时器的对象就可以实现定时作用。
用一个简单的Exp来查看定时器的使用:
/* 本实例代码展示定时器的使用 ——Beeper程序 */ #include <windows.h> #define ID_TIMER 1 LRESULT 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 1 LRESULT 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_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); //用户创建的对象需要删除 }
我们可以利用定时器来实现简单的动画屏幕保护程序:
Exp:
/* 本实例代码展示定时器的使用 ——Clock 程序 */ #include <windows.h> #include <winuser.h> #define ID_TIMER 1 LRESULT 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函数来取消定时器。