转载:从Invalidate();方法理解windows消息机制_weixin_30512785的博客-程序员宅基地

原文:http://blog.csdn.net/ghevinn/article/details/23286151

<1>
Invalidate标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。类似于PostMessage(WMPAINT),需要处理到WMPAINT消

息时才真正重绘。因为Invalidate之后还有其他的语句正在执行,程序没有机会去处理WMPAINT消息,但当函数执行完毕后,WMPAINT消息处

理才得以进行。 Invalidate只是放一个WMPAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WMPAINT,再执

行PAINT,所以不管Invalidate放哪里,都是最后的。

InvalidateRect(hWnd,&rect,TRUE);向hWnd窗体发出WMPAINT的消息,强制客户区域重绘制, rect是指定要刷新的区域,此区域外的客户区

域不被重绘,这样可以防止客户区域一个局部的改动,而导致整个客户区域重绘而导致闪烁,如果最后的参数为TRUE,则还向窗体发送

WMERASEBKGND消息,使背景重绘,当然在客户区域重绘之前。 UpdateWindow()只向窗体发送WMPAINT消息,在发送之前判断GetUpdateRect

(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WMPAINT。 如果希望立即刷新无效区域,可以在调用InvalidateRect之后

调用UpdateWindow,如果客户区的任一部分无效,则UpdateWindow将导致Windows用WMPAINT消息调用窗口过程(如果整个客户区有效,则不

调用窗口过程)。这一WMPAINT消息不进入消息队列,直接由WINDOWS调用窗口过程。窗口过程完成刷新以后立刻退出,WINDOWS将控制返回给

程序中UpdateWindow调用之后的语句。
-----------------------------------------
<2>

1. void Invalidate( BOOL bErase = TRUE );

  该函数的作用是使整个窗口客户区无效。窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口,

那么原来被遮住的部分就是无效的,需要重绘。这时Windows会在应用程序的消息队列中放置WM_PAINT消息。MFC为窗口类提供了WM_PAINT的

消息处理函数OnPaint,OnPaint负责重绘窗口。视图类有一些例外,在视图类的OnPaint函数中调用了OnDraw函数,实际的重绘工作由OnDraw

来完成。参数bErase为TRUE时,重绘区域内的背景将被擦除,否则,背景将保持不变。


它和 UpdateWindow( )区别在于:
 UpdateWindow( )的作用是使窗口立即重绘。调用Invalidate等函数后窗口不会立即重绘,这是由于WM_PAINT消息的优先级很低,它需要等

消息队列中的其它消息发送完后才能被处理。调用UpdateWindow函数可使WM_PAINT被直接发送到目标窗口,从而导致窗口立即重绘。

2. InvalidateRect只是增加重绘区域,在下次WM_PAINT的时候才生效
InvalidateRect函数中的参数TRUE表示系统会在你画之前用背景色将所选区域覆盖一次,默认背景色为白色,可以通过设置BRUSH来改变背景

色。
Invalidate()之后:(MFC的,顺便了)
OnPaint()->OnPrepareDC()->OnDraw()
所以只是刷新在OnPaint()和OnDraw()函数中的绘图语句。其它地方没有影响。
Invalidate标记一个需要重绘的无效区域,并不意味着调用该函数后就立刻进行重绘。类似于PostMessage(WM_PAINT),需要处理到WM_PAINT

消息时才真正重绘。以为您Invalidate之后还有其他的语句正在执行,程序没有机会去处理WM_PAINT消息,但当函数执行完毕后,消息处理

才得以进行。
Invalidate只是放一个WM_PAINT消息在队列里,不做别的,所以只有当当前函数返回后,进入消息循环,取出WM_PAINT,才执行PAINT,所以

不管Invalidate放哪里,都是最后的。
InvalidateRect(hWnd,&rect,TRUE);向hWnd窗体发出WM_PAINT的消息,强制客户区域重绘制,
rect是你指定要刷新的区域,此区域外的客户区域不被重绘,这样防止客户区域的一个局部的改动,而导致整个客户区域重绘而导致闪烁,

如果最后的参数为TRUE,则还向窗体发送WM_ERASEBKGND消息,使背景重绘,当然在客户区域重绘之前。
UpdateWindow只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送

WM_PAINT
如果希望立即刷新无效区域,可以在调用InvalidateRect之后调用UpdateWindow,如果客户区的任一部分无效,则UpdateWindow将导致

Windows用WM_PAINT消息调用窗口过程(如果整个客户区有效,则不调用窗口过程)。这一WM_PAINT消息不进入消息队列,直接由WINDOWS调

用窗口过程。窗口过程完成刷新以后立刻退出,WINDOWS将控制返回给程序中UpdateWindow调用之后的语句。(windows程序设计第5版 P98)
UpdateData()顺便说下,这个函数不是刷新界面用的。
UpdateData();参数为FALSE时,将界面上控件绑定的变量的数据导到控件内,参数为TRUE时,导入方向则相反。

MSDN:

Invalidate Method
Clears the object's cached user information.

Syntax


DIDiskQuotaUser.Invalidate()

Return Value


No return value.


Remarks


This method clears the user information stored in the object's cache. The next time a request is made for quota-related

information, the object retrieves the information from the NTFS volume and refreshes the cache.


Method Information


Minimum DLL version shell32.dll version 5.0 or later
Minimum operating systems Windows 2000, Windows Me

from :http://wenjuanhe.blog.163.com/blog/static/7450172520099163818916/
------------------------------------------------
<3>
Invalidata()和UpdateWindows()的关系
系统会在多个不同的时机发送WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大

化或最小化窗口时,等等,这些动作都是由系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用

也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,这一般是通过InvalidateRect和 InvalidateRgn函数来完成的

。InvalidateRect和InvalidateRgn把指定的区域加到窗口的Update Region中,当应用的消息队列没有其他消息时,如果窗口的Update

Region不为空时,系统就会自动产生WM_PAINT消息。
系统为什么不在调用Invalidate时发送WM_PAINT消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把在窗

口中的绘制操作当作一种低优先级的操作,于是尽可能地推后做,这样有利于提高绘制的效率:在两个WM_PAINT消息之间多个Invalidate调

用使之失效的区域就会被累加起来,然后在一个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是否为空等。

转载于:https://www.cnblogs.com/jianyongjohnwang/p/6797794.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30512785/article/details/99997809

智能推荐

如何利用github在.md文件中添加图片_曦曦湘涟的博客-程序员宅基地_github md图片

1、在github上的仓库建立一个存放图片的库,库的名字随意。如:Images-blog2、将需要在.md文件中显示的图片整理在一个文件夹中,然后push到Images-blog库中3、然后打开github官网,进入仓库的Images-blog库中,打开图片点击红框所示的按钮,copy地址4、在.md文件中填入:![Image](https://raw.githubuserconte...

前端工程化和webpack_温柔且无情的博客-程序员宅基地

前端工程化和webpack前端工程化简介前端工程化指的是:在企业级的前端项目开发中,把前端开发所需的工具、技术、流程、经验等进行规范化、标准化。企业中的Vue项目和React项目,都是基于 工程化 的方式进行开发的。工程化开发好处:自成体系、标准的开发方案和流程前端开发四个现代化:模块化 (JavaScript模块化、CSS模块化、静态资源模块化)组件化 (复用现有的UI结构、样式、行为)规范化 (目录结构的划分、编码规范化、接口规范化、文档规范化、Git分支管理)自动化 (自

React 学习笔记 —— redux 的使用_tanleiDD的博客-程序员宅基地

安装使用运行命令yarn add reduxredux 原理图主要流程组件 通过 Action Creators 分发(dispatch) action 给 StoreStore 将 之前的状态(previousState)、action,传递给 ReducersReducers 对状态处理后,返回给 Store 新的状态组件通过 getState() 获取状态各部分职责Action Creators: 负责生成 action 对象,并分发给 StoreStore:负

linux 查看硬件信息_永不消逝的代码的博客-程序员宅基地

linux 如何查看硬盘大小,内存大小等系统信息及硬件信息 top 可以看到不少信息 fdisk & disk - l & df 查看系统硬盘信息和使用情况 lspci 查看主板信息等 cat /proc/cpuinfo CPU信息 cat /proc/meminfo 内存信息

乘法表_刘玉元LYY的博客-程序员宅基地

#include using namespace std;int main(){ int i,j; for(i=1; i<=9; i++) { for(j=1; j<=i; j++) { cout<<j<<"*"<<i<<"="<<j*i<<" "; }

strspn() 函数_冷月醉雪的博客-程序员宅基地

查看更多https://www.yuque.com/docs/share/11c76c45-8b80-48a1-9987-2772cec86e7d

随便推点

jenkins update center遇到的坑_sunican的博客-程序员宅基地_jenkins updatecenter

目前的环境是,把jenkins.war 放在MAC 的tomcat webapps里尝试修改tomcat,添加参数:vim /Library/Tomcat//conf/context.xml &lt;Context&gt; ... &lt;Environment name="JENKINS_JAVA_OPTIONS" value="-Dhudson.model.UpdateCenter.pluginDownloadReadTimeoutSeconds=120 -Dhudson

el-table tree 改变某一个单元格背景色_aGreetSmile的博客-程序员宅基地

树状结构改变某个单元格颜色,根据层级判断是否展示数据&lt;el-table :data="tableData" style="width: 100%;" :row-key="tableRowKey" border :highlight-current-row="true" :cell-style="tableCellStyle" :tree-props="treeProps" v-on:row-click="rowClick" v-loading="loading" height="100%"&gt

二项检验_loyxCCS的博客-程序员宅基地_二项检验

文章目录检验原理西瓜书2.4节提到了二项检验,看不太懂。参考网上其他人的想法后,记录一下自己的理解。以下内容也包含着自己对假设检验的理解,内容会比较冗长。检验原理对于一个学习器的泛化错误率ϵ\epsilonϵ,我们做出一个猜想(假设):ϵ≤ϵ0\epsilon\le\epsilon_0ϵ≤ϵ0​。那么如何知道这个猜想对不对呢?假如我们已知ϵ\epsilonϵ的值,那么只需将ϵ\epsil...

数据库面经_Sebastian0819的博客-程序员宅基地

数据库系统常问面试题汇总1.数据库索引&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息。索引的一个主要目的就是加快检索表中数据的方法,亦即能协助信息搜索者尽快的找到符合限制条件的记录ID的辅助数据结构。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;优

Webmail邮件服务器搭建-有问题-邮件发出去,对方收不到_robertkun的博客-程序员宅基地

#搭建WebMail邮件服务器#1.关闭系统默认安装的 sendmail:[[email protected] ~]# service sendmail stop关闭 sendmail: [失败][[email protected] ~]#[[email protected] ~]# chkconfig --level 35 sendmail of

【sonic】sonic + zerotier 远程连接、异地连接_阿柴hp的博客-程序员宅基地

sonic 远程连接真机、设备异地连接、内网穿透

推荐文章

热门文章

相关标签