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消息:当第 ...
随机推荐
- java_13.2 Object
1.类 Object 是类层次结构的根类.每个类都使用 Object 作为超类.所有对象(包括数组)都实现这个类的方法 2.hashCode()方法 返回该对象的哈希值.一般情况下,该方法会根据对象的 ...
- centos7下apache2.4反向代理
apache安装目录在/data/apache24,这里就不介绍apache的安装了. 一.反向代理配置 在/data/apache24/conf/extra下创建htttpd-proxy.conf文 ...
- kubadm创建k8s v1.10集群
kubadm创建k8s集群 1:服务器信息以及节点介绍 主机名 ip 备注 k8s-master 192.168.0.104 master etcd keepalived k8s-client1 19 ...
- iis日志分析软件及大文本切割软件下载
在网上找了好几个日志分析软件,觉得这个是最简单.实用的,至少对我来说. 但这个软件有个缺点,就是日志比较大时,分析详细的会溢出,需要用到文本切割工具. 软件下载: iis日志分析软件 大文本切割软件 ...
- iserver-数据库型数据源导入后原dataset名称和数据库表名不一致的问题
一.发现问题 系统中发现某个房屋的分层平面图查询不到 1.去sqlserver空间库中查询发现这个表‘房间_100200T001D001’不存在 2.在工作空间中查询发现是有这个数据集的 二.解决问题 ...
- PAT 1081 检查密码(15) (代码+思路)
1081 检查密码(15 分) 本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能.该网站要求用户设置的密码必须由不少于6个字符组成,并且只能有英文字母.数字和小数点 .,还必须既有字母也 ...
- N! (大数,优化)
Problem Description 输出N的阶乘.(注意时间限制150ms&&注意不能打表后输出) 打表的定义:在本地主机预先计算出了每个值对应的答案,并把输入和输出的映射直接写入 ...
- python下的MySQL数据库编程
https://www.tutorialspoint.com/python/python_database_access.htm if you need to access an Oracle dat ...
- Codeforces 749C. Voting 模拟题
C. Voting time limit per test: 1 second memory limit per test: 256 megabytes input: standard input o ...
- dirname(__FILE__)