Invalidate(),发送WM_PAINT消息 调用 OnPaint()重绘
InvalidateRect(rect),也是发送WM_PAINT消息,调用OnPaint()重绘
两个都是调用OnPaint(), 那它们有什么区别呢?InvalidateRect(rect)仅使矩形区域无效是什么意思呢,难道矩形区域以外的地方,绘图时没有任何改变吗?
我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘时,总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口看起来在闪。
Invalidate() 使窗口无效,在重绘时,首先用背景色将显示区清除,然后再调用OnPaint()中的内容。因为背景色和绘图有反差,所以会闪烁。
而InvalidateRect(LPCRECT) ,只更新部分区域,它也是调用OnPaint()中的绘图程序,不过不同的是:它在调用OnPaint()之前,不是将所有的客户区都用背景色清除,而是仅仅将rect指定的客户区用背景色清除,rect之外的其它区域仍保留原有的绘图。
因此,使用InvalidateRect(rect)时,rect内的部分将被背景色清除,然后重新绘图,而rect外的图片仍保留,若是,OnPain()中有在rect外绘制的图形,那怎么办?很简单,用在rect外绘制的新图形冲刷掉原有的图形就可。
所以,使用这个函数时,rect之中的部分先用背景色清除,然后重新画,可能会产生闪烁;
rect之外的部分,若是新绘制的图片与原来的图片相同(rect之外的区域图片相同),则直接覆盖掉原来的图片,因为两图片相同,不会产生反差,则不会有闪烁。
rect之外的部分,若是新绘制的图片与原来不同,并且新绘制的区域范围小于原先的绘图范围时,则会呈现出一种在原先绘图基础上,将新图片叠加上去的效果-------(新图片覆盖掉原先图片等同位置的区域,而在其他区域,原图片保持不变)。
RedrawWindow(rect) 于此同理,不过RedrawWindow(rect)是立即进行更新重绘
下面是一个示例:
ONPAINT()
{
绘制图片;
绘制矩形1;
绘制矩形2;
}
在主程序中,都已经通过InvalidateRect(矩形1)将需重绘的区域进行重绘, 我想实现的效果是使:矩形区域2在绘制中不发生闪烁(我要在MOUSEMOVE消息处理中不断刷新绘制矩形1,所以矩形1会发生闪烁,但不希望矩形2也同样闪烁)。
按以上分析来说, 矩形1会发生闪烁,可为什么我的矩形2,在矩形1绘制的时候也同样发生闪烁呢?
我已经仅将矩形1的区域设置为无效了,矩形2 应该不会产生闪烁呀,因为矩形2没用背景刷子重新刷呀?
曾很苦恼这个问题,还好最后想出来了:诸位可见,在绘制矩形1前,还要绘制图片,而绘制图片不用背景刷,且重绘时,图片是相同的,所以不会闪烁,而是将原屏幕中的图片重新冲刷掉,这样,矩形2同样也被冲刷掉了,所以矩形2被重新画到图片上,由于矩形2和图片有反差,所以矩形2在刷新过程中也会看到闪烁现象。
知道原因了,可是还没用好方法解决,目前是用SetTimer(1,40,NULL); 每隔40毫秒刷新一次,而不是鼠标移动就立马刷新,暂时是缓解了矩形2跟着剧烈闪烁的现象,但还没有得到根除。
不知道,有没有好方法,可以在响应鼠标移动需要不断刷新情况下,可以让矩形2不必跟着闪烁
参考资料:
http://bbs.dlut.edu.cn/bbsanc.php?path=%2Fgroups%2FGROUP_3%2FC%2F4%2FM.1050207262.A