WM_PAINT和WM_ERASEBKGND消息
1、OnPaint()函数是窗口重绘消息WM_PAINT的响应函数,当窗口重绘时会产生WM_ERASEBKGND消息和WM_PAINT消息,而且WM_ERASEBKGND会先于WM_PAINT产生,所以窗口重绘时,会先调用OnEraseBkGnd()擦除窗口,再调用OnPaint绘制窗口。如果你在OnPaint()里自绘了窗口,在窗口重绘的时候会发现窗口会闪一下,原因就是OnEraseBkGnd()函数中使用默认的画刷(一般为灰白色)来擦除窗口。解决这个问题有三个方法:
① 在OnEraseBkGnd()中实现绘制窗口的工作,注释掉OnEraseBkGnd()中擦除窗口的代码。
② 在OnPaint中实现绘制窗口的工作,注释掉OnEraseBkGnd()中擦除窗口的代码。
③ 在OnPaint中实现绘制窗口的工作,在创建窗口时设置背景画刷为空。
由于WM_PAINT消息需要等消息队列中的其它消息发送完后才能被处理,而在OnEraseBkGnd()中实现绘制窗口的工作的话,窗口元件有任何小变动都会调用OnEraseBkGnd(),OnPaint()在调用之前OnEraseBkGnd()可能已经调用了好几次,所以最好的方法是在OnEraseBkGnd()中只做简单不耗时的绘图工作,而复杂的绘制工作在OnPaint()中进行。
窗口重绘的时候并不一定会产生WM_ERASEBKGND消息,在调用Invalidate()和InvalidateRect()重绘窗口的时候可以通过参数bErase来指定是否产生WM_ERASEBKGND消息来擦除背景。
2、Invalidate()使整个客户区无效,客户区无效则会发送WM_PAINT消息对整个客户区进行重绘。调用Invalidate后可能不会立即重绘窗口,因为它要等到消息队列中的其它消息发送完后才能被处理。函数原型:
void Invalidate( BOOL bErase = TRUE);
其参数决定了是否要在WM_PAINT消息前发送WM_ERASEBKGND消息来擦除窗口背景,bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。
InvalidateRect()同Invalidate功能相同,但可以指定重绘的区域,函数原型:
BOOL InvalidateRect(const RECT *lpRect, BOOL bErase = TRUE); UpdateWindow()会通过发送WM_PAINT消息对客户区进行重绘,如果没有可绘制的区域则不进行重绘。如果有可绘制的区域的话UpdateWindow()会立即重绘窗口,它发送的WM_PAINT消息不会进入消息队列而是直接调用窗口过程进行重绘。所以一般是调用Invalidate()后接着调用UpdateWindow()来达到窗口立即重绘的目的。函数原型:
void UpdateWindow();
RedrawWindow()也是用来使窗口重绘的,它更加灵活,其flags参数可以是下面值的组合:RDW_INVALIDATE使区域无效,RDW_UPDATENOW立即重绘窗口,RDW_ERASE重绘区域内的背景将被擦除。所以RedrawWindow()可以实现
InvalidateRect + UpdateWindow功能之和。函数原型:
BOOL RedrawWindow(
LPCRECT lpRectUpdate = NULL,
CRgn* prgnUpdate = NULL,
UINT flags = RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE
); InvalidateRgn()函数通过添加一个区域到一个窗口的更新区域中来使指定矩形的客户区域无效;这个无效的区域和所有更新区域中的其他区域将被标记用来在下一个WM_PAINT消息发生的时候描绘。
参考出处:http://www.cnblogs.com/BeyondTechnology/archive/2011/03/25/1995942.html
3、GetUpdateRect(LPRECT lpRect, BOOL bErase = FALSE)可以获得需要更新的区域,在调用了InvalidRect后可以用这个函数来获得无效区域,但如果调用了BeginPaint则获得的区域为空,所以在OnPaint中调用GetUpdateRect()无效。
GetClientRect()得到的RECT以所在窗口左上角为原点,且不包括标题栏,外框。
GetWindowRect()得到的RECT以屏幕左上角为原点,获得整个窗口的矩形。
ScreenToClient()就是把屏幕坐标系下的RECT坐标转换为客户区坐标系下的RECT坐标。
ClientToScreen()就是把客户区坐标系下的RECT坐标转换为屏幕坐标系下的RECT坐标。
WM_PAINT和WM_ERASEBKGND消息的更多相关文章
- 深度分析WM_PAINT和WM_ERASEBKGND消息
做windows开发这么久了,一直以来对WM_PAINT和WM_ERASEBKGND消息总是感觉理解的不准确,每次要自绘一个窗口都因为知其然不知其所以然,偶然发现一篇文章,详细透彻地分了这个两个消息的 ...
- WM_PAINT 与 WM_ERASEBKGND消息的深入分析
当WM_PAINT消息不是由函数InvalidateRect产生的时(即通过最大话,最小化,移动,下拉菜单等),系统会先产生连续产生若干个WM_ERASEBKGND消息,紧接着在产生WM_PAINT消 ...
- Invalidate(TRUE)与Invalidate(FALSE)区别(前者会发送WM_ERASEBKGND消息全部刷新,然后使用WM_PAINT消息绘制,而后者只发送WM_PAINT消息)
使用Invalidate(TRUE)函数时,它会向消息队列中添加了WM_ERASEBKGND和WM_PAINT两个消息. 使用Invalidate(FALSE)函数时,它只会向消息队列中添加了WM_P ...
- 窗口绘制有关的消息整理 WM_PAINT, WM_NCPAINT, WM_ERASEBKGND
WM_PAINTWM_PAINT是Windows窗口系统中一条重要的消息,应用程序通过处理该消息实现在窗口上的绘制工作. WM_NCPAINT当窗口客户区以外的部分(如窗口标题栏.菜单栏等)需要需要重 ...
- WM_PAINT与WM_ERASEBKGND(用户操作和API这两种情况产生消息的顺序有所不同)
1)当WM_PAINT不是由InvalidateRect产生时,即由最大化,最小化等产生时,或者移动产生(移动有时只会产生WM_ERASEBKGND消息)系统先发送WM_ERASEBKGND消息,再发 ...
- 终于懂了:WM_PAINT 与 WM_ERASEBKGND(三种情况:用户操作,UpdateWindow,InvalidateRect产生的效果并不相同),并且用Delphi代码验证 good
一直对这两个消息的关系不是太了解,借重新深刻学习windows编程的机会研究一番. 1)当窗口从无效变为有效时,比方将部分覆盖的窗口恢复时会重绘窗口时:程序首先会通过发送其他消息调用DefWindow ...
- WM_PAINT产生原因有2种(用户操作和API)——WM_PAINT和WM_ERASEBKGND产生时的先后顺序不一定(四段讨论)
1. 当WM_PAINT不是由InvalidateRect产生时,即由最大化,最小化等产生时,或者移动产生(移动有时只会产生WM_ERASEBKGND消息)系统先发送WM_ERASEBKGND消息,再 ...
- 关于WM_ERASEBKGND和WM_PAINT的深刻理解
一直以来,对于WM_PAINT和WM_ERASEBKGND消息不是很清楚,从书上和网上找了很多资料,大体上有以下几点说法:1>WM_PAINT先产生,WM_ERASEBKGND后产生 2.WM_ ...
- WM_PAINT消息小结
WM_PAINT是Windows窗口系统中一条重要的消息,应用程序通过处理该消息实现在窗口上的绘制工作. 1. 系统何时发送WM_PAINT消息? 系统会在多个不同的时机发送WM_PAINT消息:当第 ...
随机推荐
- h5外部浏览器直接调起app
1. 安卓端: 其中,scheme必须是小写的,同时要求H5必须是“<a href="appback://">启动应用程序</a> ” 2. h5端完整示例 ...
- java 異常抛出 throw 與 return
package 異常; public class TestException { public TestException() { } boolean test ...
- 8.16 val()和html()的问题
今天在做关闭模态框重置表单时,关闭模态框后输入框里的值还是在,不知道怎么回事? 感谢wd啦,原来我在初始化这个输入框的时候就写错了,输入框写值的时候用的是val(),而我和上面的div一样,用的是ht ...
- day 13 模块
模块 一个py文件,就是一个模块,一个模块是一些相似功能的集合体. # echo.py 定义一个模块. 下文都用这个 print('from echo 模块') name = 'echo' def f ...
- mysql乐观锁总结和实践(二)
一篇文章<MySQL悲观锁总结和实践>谈到了MySQL悲观锁,但是悲观锁并不是适用于任何场景,它也有它存在的一些不足,因为悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占 ...
- 15.Mysql中的安全问题
15.SQL中的安全问题15.1 SQL注入简介SQL是用来和数据库交互的文本语言.SQL注入(SQL Injection)是利用数据库的外部接口将用户数据插入到实际的SQL中,以达到入侵数据库乃至操 ...
- java 字符串截取类 区分中文、英文、数字、标点符号
package com.founder.fix.ims; /** * @author WANGYUTAO * 操作字符串 */ public class SubString { // public s ...
- Tech 2 doesn’t system for H2 above 2007
I purchased my Tech2 from obd2tool.com and it operates excellent. Can not definitely compare softwar ...
- NGS基础 - 高通量测序原理
NGS基础 - 高通量测序原理 原创: 赑屃 生信宝典 2017-07-23 NGS系列文章包括NGS基础.转录组分析.ChIP-seq分析.DNA甲基化分析.重测序分析五部分内容. NGS基础系列文 ...
- BZOJ 3329 - Xorequ - 数位DP, 矩乘
Solution 发现 $x \ xor \ 2x = 3x$ 仅当 $x$ 的二进制中没有相邻的 $1$ 对于第一个问题就可以进行数位DP 了. 但是对于第二个问题, 我们只能通过递推 打表 来算 ...