在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函数来取消定时器。