Visual C++——定时刷新重绘窗口[WM_PAINT消息]解决方案

1012 篇文章 45 订阅

基本概念

定时器:每隔一定时间执行一次的任务。

API

SetTimer的函数原型: 

UINT_PTR SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc ) ; 

其中 

hWnd是和timer关联的窗口句柄,此窗口必须为调用SetTimer的线程所有;如果hWnd为NULL,没有窗口和timer相关联并且nIDEvent参数被忽略 

nIDEvent是timer的标识,为非零值;如果hWnd为NULL则被忽略;如果hWnd非NULL而且与timer相关联的窗口已经存在一个为此标识的timer,则此次SetTimer调用将用新的timer代替原来的timer。timer标识和窗口相关,两个不同的窗口可以拥有nIDEvent相同的tiemr 

uElapse是以毫秒指定的计时间隔值,范围为1毫秒到4,294,967,295毫秒(将近50天),这个值指示Windows每隔多久时间给程序发送WM_TIMER消息。 

lpTimerFunc是一个回调函数的指针,俗称TimerFunc;如果lpTimerFunc为NULL,系统将向应用程序队列发送WM_TIMER消息;如果lpTimerFunc指定了一个值,DefWindowProc将在处理WM_TIMER消息时调用这个lpTimerFunc所指向的回调函数,因此即使使用TimerProc代替处理WM_TIMER也需要向窗口分发消息。 

返回值:如果hWnd为NULL,返回值为新建立的timer的ID,如果hWnd非NULL,返回一个非0整数,如果SetTimer调用失败则返回0 

KillTimer的函数原型:

BOOL KillTimer( HWND hWnd, UINT_PTR uIDEvent ) ;

InvalidateRect的函数原型:

BOOL InvalidateRect(

HWND hWnd, // handle of window withchanged update region 窗口句柄。

CONST RECT *lpRect, // address ofrectangle coordinates rect结构体的指针。

BOOL bErase // erase-background flag 是否要发送WM_ERASEBKGND消息从而擦除原来的背景

);

作用:使得Client的一个矩形区域变得无效,rect结构体可以自己编辑,也可以使用GetClientRcet()来填充(这里的矩形大小Client的大小),

最主要的是第三个参数,第三个参数决定了是否发送WM_ERASEBKGND消息,从而决定了是否擦除Client原有的图形。

关于WM_TIMER消息 

wParam为计时器的ID;

如果需要设定多个计时器,那么对每个计时器都使用不同的计时器ID。

wParam的值将随传递到窗口过程中的WM_TIMER消息的不同而不同。 

lParam为指向TimerProc的指针,如果调用SetTimer时没有指定TimerProc(参数值为NULL),则lParam为0(即NULL)。 
可以通过在窗口过程中提供一个WM_TIMER case处理这个消息,或者,默认窗口过程会调用SetTimer中指定的TimerProc来处理

解决方案

例:每隔一秒(1000毫秒)执行一次,但每次的情况不同,所以用一个BOOL类型的变量来标识,如果为TRUE就在WM_PAINT事件中把窗口的客户区域填充为红色,如果为FALSE就不填充。如此,就可以使得窗口呈现出一闪一闪的效果。 

// Timer的回调函数
VOID CALLBACK TimerProc(
  _In_  HWND hwnd,
  _In_  UINT uMsg,
  _In_  UINT_PTR idEvent,
  _In_  DWORD dwTime
)
{
	isBorderDrawed = !isBorderDrawed;
	RECT rect;
	GetClientRect(hwnd,&rect);
	InvalidateRect(hwnd, &rect, TRUE);
}
        /* 处理WM_PAINT消息 */
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
	    // 获取窗口边框矩形
		RECT rect;
		GetClientRect(hWnd, &rect);
		if (isBorderDrawed)
		{
			HBRUSH hb = CreateSolidBrush(RGB(255,0,0));
			FillRect(hdc,&rect, hb);
			SelectObject(hdc,hb);
		}
		EndPaint(hWnd, &ps);
		break;

 运行结果

 

参考文章

https://shentuzhigang.blog.csdn.net/article/details/105288759

https://blog.csdn.net/u012104827/article/details/105278079/

https://blog.csdn.net/tcjiaan/article/details/8916626

https://blog.csdn.net/u011580175/article/details/56354223

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Starzkg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值