关于OnPaint函数的工作原理(很详细,很实用)
来源:互联网 发布:生死疲劳 知乎 编辑:程序博客网 时间:2024/05/28 17:04
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函数的工作原理(很详细,很实用)
- 关于OnPaint函数的工作原理(很详细,很实用)
- 关于OnPaint函数的工作原理(很详细,很实用)
- 关于OnPaint函数的工作原理(很详细,很实用)
- OnPaint()的工作原理
- MFC的OnPaint工作原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- OnPaint()函数的作用原理
- C++中对象的内存分布
- 杭电1695GCD【欧拉函数】【容斥定理】
- smail语法 详解
- Redis基础学习--安装、简介、基本数据类型及相应命令
- Hibernate一级缓存——Session
- 关于OnPaint函数的工作原理(很详细,很实用)
- 【leetcode】Linked List —— easy(java)
- 【01】 windows 下搭建Perl 开发环境
- 灵活而奇特的C++语言特性——作用域解析(二)
- linux环境C开发系列1-一些函数
- MVC框架中Controller层经常做的那些事!
- matlab图像处理
- malloc函数实现原理!
- KendoUI使用日记(一)TreeList