Windows程序设计零基础自学_7_定时器的使用

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

你可能感兴趣的:(windows)