���¼���ԭʼ��ҳ��ӡ

从Invalidate();方法理解Windows消息机制 - Ghevinn欢迎您光临 - 博客频道

<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是否为空等。

�Ķ�ģʽ — An Arc90 Laboratory Experiment 

转载于:https://www.cnblogs.com/Dennis-mi/articles/4546064.html

Windows 窗体重绘相关推荐

  1. java画图缩小就没有了_Java窗体重绘:解决改变窗体后图形消失问题

    我们用所学做了个Java的绘图板,然后可以画些图形上去.但是我们后来发现一个小小der问题,就是这样 我们只要改变窗体大小,或者最小化再打开窗体.或者把窗体移到屏幕外,就有这样一个问题:我们画的图案不 ...

  2. Windows 窗设计时结构

    Windows 窗设计时结构 Windows 窗体编程 设计时结构 下面的阐释概述了 .NET Framework 中的设计时结构. screen.width*0.7) {this.resized=t ...

  3. Windows Phone简易绘画板(续)

    Windows Phone简易绘画板:http://blog.csdn.net/crazy_frog/article/details/7565780 在原本的基础上,继续完善了清除墨迹和保存图片的功能 ...

  4. Windows Phone简易绘画板

    启动画面: 主画面: using System; using System.Collections.Generic; using System.Linq; using System.Net; usin ...

  5. Windows窗口中的F10快捷键

    按F10的时候相当于按下了选中菜单的快捷键(相当于Alt键): 想要关掉这个特性,可以选择在窗口回调中截获WM_SYSKEYDOWN或者WM_SYSKEYUP这两个消息的其中一个,那么就不会产生这种奇 ...

  6. Windows屏幕工具(屏幕截图、贴图/屏幕取色/截图文字、表格识别/截图翻译、GIF录屏、GIF压缩)

    背景 你是不是每次要截图而需要打开微信或者QQ截图而感到麻烦,你是不是经常被类似某度文库不能复制文字而感到不爽,你是不是在需要获取屏幕上某个颜色而到处找工具,你是不是想将屏幕操作生成动图图分享给其他人 ...

  7. pcie转m2装系统win10_M.2接口NVMe SSD固态驱动器安装win10

    01-04阅读20,000 + [前言]本教程主要用于笔记本电脑安装,但也适用于高端台式机安装. 什么用例适合?例如,美国版的笔记本电脑ThinkPad XPS价格昂贵,但是安装盗版系统将失去许多必要 ...

  8. C# GDI+双倍缓冲技术

    在C#Windows窗体中开发游戏时,会发现屏幕发生闪烁,那如何进行解决呢?这就用到了GDI+的双倍缓冲技术: 导致画面闪烁的原因: 随着游戏的进行,窗体内容在不断变化,每次都要调用paint事件来进 ...

  9. 控件重叠 关于WS_CLIPCHILDREN和WS_CLIPSIBLINGS的理解(个人认为还是相当全面的)

    WS_CLIPCHILDREN样式从字面上可以理解成ClipChildren,裁减子窗口. MSDN里的E文解释:Excludes the area occupied by child windows ...

最新文章

  1. python【数据结构与算法】内置函数enumerate(枚举) 函数(看不懂你来打我)
  2. LAMP架构之编译安装httpd+(php-fpm)+mariadb
  3. Matlab:成功解决Index must be a positive integer or logical
  4. 如何在局域网访问Tomcat项目
  5. sklearn.metrics.roc_curve
  6. CentOS7-Python系列】之一【python-devel教训】
  7. [python基础]关于中文编码和解码那点事儿
  8. SQLyog下载地址—Mysql的可视化(建议收藏)
  9. java拉起服务,从Java调用Restful服务
  10. JavaScript DOM 编程艺术(第2版)读书笔记 (7)
  11. fortan程序设计
  12. linux关闭端口进程命令,linux关闭端口命令
  13. 骑士cms,骑士cms快速搭建
  14. Vue实现百度离线地图(v2.0)
  15. Win10系统修改开机密码
  16. 迷茫时的3个选择,决定了你人生的高度
  17. VMware复制ubuntu16虚拟机时提示句柄无效解决方法
  18. notifier_call -----总结
  19. 在官网上下载慢解决办法
  20. HEVC中低复杂度量化技术

热门文章

  1. webstorm配置,快捷键console.log,中文字体,快捷键配置等
  2. SpringBoot FK-关联表查询(三)
  3. Java连接Elasticsearch6.xxx 环境测试篇一
  4. .Net面试题汇总(一) 帮你轻松过笔试关
  5. 利用jquery load 局部刷新数据
  6. Magento: 设置产品列表默认排序方式 How to sort Magento products by date added as default
  7. visibility: hidden与display:none的区别
  8. 在Shell中使用函数文件,引入文件
  9. CakePHP你必须知道的21条技巧
  10. 最短路径——Dijkstra算法HDU Today(hdu2112)