转载出处:http://blog.csdn.net/foreverhuylee/article/details/21889025

  用了两年的VC++,其实对OnPaint的工作原理一直都是一知半解。这两天心血来潮,到BBS上到处发帖询问,总算搞清楚了,现在总结一下。

  对于窗口程序,一般有个特点:窗口大部分的区域保持不变,只有部分区域需要重新绘制。如果将整个窗口全部刷新的话,就做了许多不必要的工作,因而,MFC采用了一套基于无效区域的处理机制。在分析无效区域处理之前,我们要明白一个现实:现在的机器还不够牛,如果够牛的话,我们干脆将整个窗口不断的重新绘制好了。事实上即使够牛也不行,对于一个单线程程序,通过一个while循环不断的刷新窗口,程序也无法相应其他消息(除非使用多线程),看来使用无效区域的处理机制还是有其必然性的。

VC++程序是基于消息机制的,你所做的任何操作,比如点击鼠标,拖动窗口,首先进入系统的消息队列。这里的系统消息队列包括多个程序的消息,系统再将消息发送给相应的程序。既然是队列,这就有一个先进先出的问题,屏幕上的无效区更新消息出现的频率就会特别高。比如当左上角更新的消息还没有处理,右下角更新的消息已经过来了。为了避免多次处理WM_PAINT消息,系统就将这些窗口更新消息合并到一条,只是将无效区范围变成包括这两次更新无效区范围在内的矩形区域。这样就减少了WM_PAINT消息的处理次数,提高了效率。

  那么,在OnPaint消息处理函数中,又是怎样实现更新无效区域的呢?

  首先,要明白MFC中所有绘图操作都是基于设备描述表(Device Context,简称DC)的,具体信息可参看任何一本VC++教材。DC中包含了绘图设备的各种信息,对于屏幕绘图,其实就是有一块内存(显存),专门用来存放要显示到屏幕上的信息,显示器以85HZ的频率(我以前的显示器)将其内容刷新的屏幕上。这里就到了关键点,显示器的刷新是将显存中的内容完全更新到显示器上,不存在无效区处理的问题,那么,无效区的处理一定发生在DC的绘图处理上。事实确实如此,当程序调用OnPaint消息时,首先将无效区范围传递给DC,DC在进行绘图操作时,就只更新无效区范围内的信息,其他地方的不管,这就提高了效率。

  开启OnPaint函数有下面三种选择:

  1)、直接发送WM_PAINT消息,用PostMessage(),SendMessage()函数发送WM_PAINT消息。使用以上两函数发送WM_PAINT消息,能将WM_PAINT消息发送到WINDOWS程序消息队列中,当WINDOWS将WM_PAINT消息发送给具体的消息处理函数时,如果窗口的无效区域为空则WINDOWS将不理睬该消息。若存在无效区域,则调用窗口处理函数处理。要注意的这里需要存在无效区域,因此要调用2)中的函数使得窗体(或者部分)无效,其处理过程与2)相同,将WM_PAINT消息送入消息处理队列。与3)不同的是WM_PAINT并不立即处理;

  2)、调用相应的API实现WM_PAINT消息的发送:Invalidate(),InvalidateRect(), InvalidateRgn():以上函数将窗口的特定区域标定为无效,当WINDOWS检测到窗口中存在无效区域时将向消息队列发送WM_PAINT 消息。我当时用的就是Invalidate()函数;

  3)、UpdateWindow():该函数调用后WINDOWS将向窗口发送一个非队列化的WM_PAINT消息,它不经过消息循环而直接发送给了窗口消息处理函数。如果窗口无效区域不存在,WINDOWS将不理睬该消息。注意这里因为要使得窗口无效区不存在,因此还是调用Invalidate(),InvalidateRect(), InvalidateRgn()函数,和2)中不同的是这里的WM_PAINT消息会被立即处理,而2)中是加入消息处理队列。

  简单起见,你可以使用2)中方案进行问题解决。

  现在你明白OnPaint的处理是怎么一回事了吧?

  这里还想说一下Invalidate和UpdateWindow的区别。

  Invalidate在消息队列中加入一条WM_PAINT消息,其无效区为整个客户区。而UpdateWindow直接发送一个WM_PAINT消息,其无效区范围就是消息队列中WM_PAINT消息(最多只有一条)的无效区。效果很明显,调用Invalidate之后,屏幕不一定马上更新,因为WM_PAINT消息不一定在队列头部,而调用UpdateWindow会使WM_PAINT消息马上执行的,绕过了消息队列。如果你调用Invalidate之后想马上更新屏幕,那就加上UpdateWindow()这条语句。

【转】关于OnPaint的工作机制的更多相关文章

  1. android 6.0 高通平台sensor 工作机制及流程(原创)

    最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...

  2. Java IO工作机制分析

    Java的IO类都在java.io包下,这些类大致可分为以下4种: 基于字节操作的 I/O 接口:InputStream 和 OutputStream 基于字符操作的 I/O 接口:Writer 和 ...

  3. malloc 函数工作机制(转)

    malloc()工作机制 malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表.调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块.然后,将 ...

  4. springMVC工作机制和框架搭建配置说明

    先说一下springMVC的工作机制 1.springmvc把 所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作. 2.Dispatcher ...

  5. CKPT进程工作机制

    CKPT进程工作示意图 2.CKPT进程工作机制 检查点进程被触发的条件为: a> 当发生日志组切换时: b>  用户提交了事务时(commit): c>  Redo log buf ...

  6. 15 sql base line 工作机制

    <个人Configuration> 正常配置一下, 就OK了, 不用理了, oracle 11g 默认启动 发展: .从Oracle的发展角度来看,估计这种方法是Oracle发展和改进的方 ...

  7. HBase读写路径的工作机制

    出处:http://wuyudong.com/1946.html HBase 写路径工作机制 在HBase 中无论是增加新行还是修改已有的行,其内部流程都是相同的.HBase 接到命令后存下变化信息, ...

  8. PHP自动加载__autoload的工作机制

    PHP自动加载__autoload的工作机制 PHP的懒加载lazy loading 在 2011年11月12日 那天写的     已经有 4559 次阅读了 感谢 参考或原文   服务器君一共花费了 ...

  9. hadoop MapReduce 工作机制

    摸索了将近一个月的hadoop , 在centos上配了一个伪分布式的环境,又折腾了一把hadoop eclipse plugin,最后终于实现了在windows上编写MapReduce程序,在cen ...

随机推荐

  1. 理解HTTP/304响应

    理解HTTP/304响应 原文:http://www.telerik.com/automated-testing-tools/blog/eric-lawrence/12-11-06/understan ...

  2. 逻辑回归的相关问题及java实现

    本讲主要说下逻辑回归的相关问题和详细的实现方法 1. 什么是逻辑回归 逻辑回归是线性回归的一种,那么什么是回归,什么是线性回归 回归指的是公式已知,对公式中的未知參数进行预计,注意公式必须是已知的,否 ...

  3. PHP-根据字符串和所用字体计算字符串所占宽高

    今天由于用GD画图, 需要把一段文字在一个框内居中, 但是文字的宽度如果用strlen($str) * $font_size来计算的话, 由于文字不是等宽高的, 所以会导致偏离, 最后选用的GD库的i ...

  4. Linux下SSH免密码登录(转)

    搭建hadoop集群的时候一定会用到的就是SSH免密码登录 [hadoop@hadoop1 ~]$ ssh-keygen -t rsa Generating public/private rsa ke ...

  5. Android4.0源码Launcher启动流程分析【android源码Launcher系列一】

    最近研究ICS4.0的Launcher,发现4.0和2.3有稍微点区别,但是区别不是特别大,所以我就先整理一下Launcher启动的大致流程. Launcher其实是贯彻于手机的整个系统的,时时刻刻都 ...

  6. iOS 获得通讯录中联系人的所有属性--b

    ABAddressBookRef addressBook = ABAddressBookCreate(); CFArrayRef results = ABAddressBookCopyArrayOfA ...

  7. [Asp.net]IIS经典和继承模式

    引言 由于要在客户那里部署项目,就研究了一下IIS中的集成和经典模式,这里做一些笔记.希望对您有所帮助. IIS7.0和IIS6.0 IIS7.0的web应用程序有两种配置模式:经典模式和集成模式.经 ...

  8. nginx实战二

    nginx架构分析 1.nginx模块化 Nginx涉及到的模块分为核心模块.标准HTTP模块.可选HTTP模块.邮件服务模块以及第三方模块等五大类. https://coding.net/u/ami ...

  9. pandas set_index和reset_index的用法

    1.set_index DataFrame可以通过set_index方法,可以设置单索引和复合索引. DataFrame.set_index(keys, drop=True, append=False ...

  10. XVAG音频文件格式提取

    索尼的一种游戏音频格式,通过vgmstream工具可以提取 工具已经下载好:(包含dll包) http://files.cnblogs.com/files/hont/vgmstream-r1040-t ...