开发者社区> double2li> 正文

WM_PAINT消息小结

简介: WM_PAINT是Windows窗口系统中一条重要的消息,应用程序通过处理该消息实现在窗口上的绘制工作。 1. 系统何时发送WM_PAINT消息? 系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口时,等等,这些动作都是由 系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,这一般是通过InvalidateRect和 InvalidateRgn函数来完成的。
+关注继续查看

WM_PAINT是Windows窗口系统中一条重要的消息,应用程序通过处理该消息实现在窗口上的绘制工作。

1. 系统何时发送WM_PAINT消息?

系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口时,等等,这些动作都是由 系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,这一般是通过InvalidateRect和 InvalidateRgn函数来完成的。InvalidateRect和InvalidateRgn把指定的区域加到窗口的Update Region中,当应用的消息队列没有其他消息时,如果窗口的Update Region不为空时,系统就会自动产生WM_PAINT消息。

系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把在窗口中的绘制操作当作一种低优先级的操作,于是尽 可能地推后做。不过这样也有利于提高绘制的效率:两个WM_PAINT消息之间通过InvalidateRect和InvaliateRgn使之失效的区域就会被累加起来,然后在一个WM_PAINT消息中一次得到 更新,不仅能避免多次重复地更新同一区域,也优化了应用的更新操作。像这种通过InvalidateRect和InvalidateRgn来使窗口区域无效,依赖于系统在合适的时机发送WM_PAINT消息的机 制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT消息之间是有延迟的;有时候这种延迟并不是我们希望的,这时我们当然可以在无效化窗口区域后利用SendMessage 发送一条WM_PAINT消息来强制立即重画,但不如使用Windows GDI为我们提供的更方便和强大的函数:UpdateWindow和RedrawWindow。UpdateWindow会检查窗口的Update Region,当其不为空时才发送WM_PAINT消息;RedrawWindow则给我们更多的控制:是否重画非客户区和背景,是否总是发送WM_PAINT消息而不管Update Region是否为空等。

2. BeginPaint

BeginPaint和WM_PAINT消息紧密相关。试一试在WM_PAINT处理函数中不写BeginPaint会怎样?程序会像进入了一个死循环一样达到惊人的CPU占用率,你会发现程序总在处理一个接 一个的WM_PAINT消息。这是因为在通常情况下,当应用收到WM_PAINT消息时,窗口的Update Region都是非空的(如果为空就不需要发送WM_PAINT消息了),BeginPaint的一个作用就是把该Update Region置为空,这样如果不调用BeginPaint,窗口的Update Region就一直不为空,如前所述,系统就会一直发送WM_PAINT消息。

BeginPaint和WM_ERASEBKGND消息也有关系。当窗口的Update Region被标志为需要擦除背景时,BeginPaint会发送WM_ERASEBKGND消息来重画背景,同时在其返回信息里有一个标志表明窗口背景是否被重画过。当我们用InvalidateRect和InvalidateRgn来把指定区域加到Update Region中时,可以设置该区域是否需要被擦除背景,这样下一个BeginPaint就知道是否需要发送WM_ERASEBKGND消息了。

另外要注意的一点是,BeginPaint只能在WM_PAINT处理函数中使用。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
DECLARE_MESSAGE_MAP() 等消息映射宏以及 afx_msg消息映射函数
DECLARE_MESSAGE_MAP() 等消息映射宏以及 afx_msg消息映射函数
155 0
[141204]11G关于使用wmsys.wm_concat的问题
[20141204]11G关于使用wmsys.wm_concat的问题.txt --今天开发提示一些sql语句在dataguard查询时报错,因为dataguard是read only打开,一些dml语句是不支持的, --没看语句之前,以为是语句里面使用sequence,仔细检查发现没有,而发现使用了wmsys.wm_concat。
1237 0
WM_CTLCOLOR消息 .
参考文章:白乔原创:VC之美化界面篇         在每个控件开始绘制之前,都会向其父窗口发送WM_CTLCOLOR通告消息,在该消息的处理函数中,可以设置控件显示文本的前景色、背景色以及字体。该消息处理函数还要求返回一个画刷的句柄,用于在控件具体的绘制之前擦除其客户区。
862 0
WM_CREATE和WM_INITDIALOG
WM_CREATE和WM_INITDIALOG消息响应函数之区别,以及MFC应用程序中处理消息的...        在响应WM_CREATE消息响应函数的时候,对话框及子控件还未创建完成,亦是说只是通知系统说要开始创建窗口啦,这个消息响应完之后,对话框和子控件才开始创建。
933 0
WM_NCHITTEST消息说明
文章来源:http://blog.csdn.net/yingzheng1983/article/details/3135858 WM_NCHITTEST 当光标移动到窗体,或鼠标按下,释放时,发送WM_NCHITTEST消息,如何鼠标不被捕获,消息在窗体得到光标之后发出,否则,消息发送到捕获到鼠标的窗体。
535 0
MFC与SDK中的重画问题 。。WM_PAINT消息的处理
  在基于多文档的应用程序  CView的重绘为例子SD   在 K中我们是拦截 WM_PAINT 消息进行 重回的处理 只要 窗体一出现Invalid Area 那么都需要重绘    在MFC中 WM_PAINT 消息的响应函数 是 OnPaint() 但是为什么重绘 我们一直在 O...
717 0
使用WM_CHAR消息来限制用户的输入
在做管理系统的时候,经常要限制用户的输入,如,只可以输入数字,等等 net 下限制用户输入,很多人是在键盘,或 textBox 的 TextChanged 事件里这样做1.不能限制用户的粘贴2.严重干扰数据绑定等操作3.有时还需要备份原始数据进行还原限制输入的时机是在,windows 消息 WM_CHAR 触发时但.net 恰恰没有提供这个消息的事件映射.   继承TextBox 重写 Wn
787 0
+关注
double2li
一个在IT行业摸爬滚打的老司机
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载