八、定时器

8.1定时器基本知识
	SetTimer:分配一个定时器,有一个间隔范围为1毫秒到4,294,967,295秒(约50天)的整形参数。指示间隔发送WM_TIMER的时间	KillTimer:停止定时器消息。如我们可以调用该函数写一个只限用一次的定时器。该函数调用清除消息队列中未处理的WM_TIMER消息

系统和定时器
	win本身处理硬件中断,应用程序无需处理。对于拥有定时器的程序(win存储每个硬件timertick减少次数),当该计数减为0时,win在应用程序消息队列中放入一个WM_TIMER消息,并重置计数初值。
	定时器消息不是异步的,无需担心WM_TIMER会中断程序的执行。和WM_PAINT消息类似:不会向消息队列中放入多个WM_PAINT消息,而是将多余的该消息组成一个。WM_TIMER消息仅在需要更新时才提示程序,所以程序本身不能由WM_TIMER消息数目来计时。
这两个消息都是低优先级的,程序只有在消息队列中没有其他消息时才接收它们。
 
定时器的三种使用方法
如果要在整个程序执行期间使得定时器,可以在WinMain或WM_CREATE中调用SetTImer。在退出或响应WM_DESTROY时调用用KillTimer。
方法一
win发送WM_TIMER至应用程序正常窗口消息处理程序。(最常用)
#define ID_TIMER 1
//每隔一秒重绘客户区
LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, WPARAM wParam,LPARAM lParam)
{
	static BOOL flag=FALSE;  //标志符
	HBRUSH hBrush;
	RECT rect;
	HDC hdc;
	PAINTSTRUCT ps;
	switch (message)
	{
	case WM_CREATE:
		SetTimer(hwnd,ID_TIMER,1000,NULL); //设定定时器
		return 0;

	case WM_TIMER:
		MessageBeep(-1);
		flag=!flag;
		InvalidateRect(hwnd,NULL,TRUE);//NULL,全部的窗口客户区将更新
		return 0;

	case WM_PAINT:
		hdc=BeginPaint(hwnd,&ps);
		hBrush=CreateSolidBrush(flag?RGB(255,0,0):RGB(0,255,0));
		GetClientRect(hwnd,&rect); //填充之前一定要确定填充范围
		FillRect(hdc,&rect,hBrush);
		EndPaint(hwnd,&ps);
		DeleteObject(hBrush);
		return 0;

	case WM_DESTROY:
		KillTimer(hwnd,ID_TIMER);//清除定时器,清除所有WM_TIMER消息
		PostQuitMessage(0);
		return 0;
	default:
		break;
	}
	return DefWindowProc(hwnd,message,wParam,lParam);
}

方法二
win直接将定时器消息发送给程序的另一个函数。接收这些消息的函数被称为(callback函数),必须定义为CALLBACK(因为它是由win从程序代码段中调用)。其参数和返回值取决于函数目的。
VOID CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime);
LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_CREATE:
		SetTimer (hwnd, ID_TIMER, 1000, TimerProc) ;//win发送消息给TimerProc,而非法一中发送给WindowProc
		//和方法一最后一个参数不同
		return 0 ;
	case WM_DESTROY:
		KillTimer (hwnd, ID_TIMER) ;
		PostQuitMessage (0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
VOID CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)//hwnd SetTimer中的窗口句柄
{
	static BOOL flag = FALSE ;
	HBRUSH hBrush ;
	HDC hdc ;
	RECT rc ;
	MessageBeep (-1) ;
	flag=!flag;
	GetClientRect (hwnd, &rc) ;
	hdc = GetDC (hwnd) ;
	hBrush = CreateSolidBrush (flag ? RGB(255,0,0) : RGB(0,0,255)) ;
	FillRect (hdc, &rc, hBrush) ;
	ReleaseDC (hwnd, hdc) ;
	DeleteObject (hBrush) ;
}
方法三
和法二类似,只是传递给SetTimer参数hwnd设为NULL。且第二个参数(一般为计时器ID)被忽略。最后传回此ID。(传递给TimerProc的参数也必须是NULL,很少用,如果在某时刻有一系列SetTimer调用,但又不想使用过的定时器ID被追踪,这方法很方便。)
iTimerID=SetTimer(NULL,0,wMsecInterval,TimerProc);//hwnd为NULL
KillTimer(NULL,iTimerID);  //hwnd也为NULL
8.3定时器用于时钟
数字时钟
模拟时钟
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值