窗口刷新问题(WM_PAINT、BeginPaint、EndPaint的说明)计算机二级考试
文章作者 100test 发表时间 2009:06:15 10:08:29
来源 100Test.Com百考试题网
编辑特别推荐:
全国计算机等级考试(等考)指定教材
全国计算机等级考试学习视频
全国计算机等级考试网上辅导招生
全国计算机等级考试时间及科目预告
百考试题教育全国计算机等级考试在线测试平台
全国计算机等级考试资料下载
全国计算机等级考试论坛
计算机等级考试四级应用题解析汇总
2009年下半年全国计算机二级考试报名时间从6月1日起已经开始报名。详情点击:2009年下半年全国计算机等级考试各地报名点汇总。2009年下半年全国计算机二级考试时间是2009年9月19日至23日。更多优质资料尽在百考试题论坛 百考试题在线题库。
在Windows API编程中,WM_PAINT是Windows窗口的一个重要消息,应用程序就是通过响应这个消息来完成窗口的绘制。
The WM_PAINT message is generated by the system and should not be sent by an application.The system sends this message when there are no other messages in the application s message queue
注意:WM_PAINT消息是由系统产生,非要等应用程序的消息队列为空时才发送WM_PAINT消息。
其实系统会在很多的不同的机制下发送WM_PAINT消息,比如调用UpdateWindow函数,第一次创建窗口,改变了窗口的大小,最大化,最小化等等。这些动作的产生都是有系统来控制的,应用程序只是接收消息,并处理消息。
当Window检测到窗口被覆盖的地方需要恢复的时候,它会向用户程序发送一个WM_PAINT消息,消息中包括了需要恢复的区域,然后由用户程序来决定如何恢复被覆盖的内容。窗口过程收到WM_PAINT消息后,并不代表整个客户区都需要被刷新,有可能客户区被覆盖的区域只有一小块,这个区域叫做“无效区域”,程序只需要更新这个区域。与WM_TIMER消息类似,WM_PAINT消息也是一个低级别的消息,虽然它不会像WM_TIMER消息一样被丢弃,但Windows总是在消息循环空的时候才把WM_PAINT放入其中,实际上,Windows为每个窗口维护一个“绘图信息结构”,无效区域的坐标就在其中,每当消息循环空的时候,如果Windows发现存在一个无效区域,就会放入一个WM_PAINT消息。
无效区域的坐标并不附带在WM_PAINT消息的参数中,在程序中有其他方法可以获取,WM_PAINT消息只是通知程序有个区域需要更新而已,所以Windows也不会同时将两条WM_PAINT消息放入消息循环中,当Windows要放入一条WM_PAINT消息的时候,如果发现已经存在一个无效区域了,那么它只需要把新旧两个无效区域合并计算出一个无效区域就可以了,消息循环中还是只需要一条WM_PAINT消息。
如果程序在WM_PAINT消息中对客户区刷新完毕后工作并没有结束,如果不使无效区域变得有效,Windows会在下一轮消息循环中继续放入一个WM_PAINT消息,而不是根据程序是否执行了刷新过程,所以程序也可以不去刷新客户区,而是简单地用一个ValidateRect函数直接让客户区变得有效,以此来“欺骗”Windows已经没有无效区域了,当Windows检查“绘图信息结构”的时候发现没有了无效区域,也就不会继续发送WM_PAINT消息了。
那么“绘图信息结构”怎么获取呢?BeginPaint函数的第二个参数是一个绘图信息结构的缓冲区地址,windows会在这里返回绘图信息结构,结构中包含了无效区域的位置和大小,绘图信息结构的定义如下:
typedef struct tagPAINTSTRUCT { // ps
HDC hdc.
BOOL fErase.
RECT rcPaint.
BOOL fRestore.
BOOL fIncUpdate.
BYTE rgbReserved[32].
} PAINTSTRUCT.
其中hdc字段是窗口的设备环境句柄,rcPaint字段是一个RECT结构,它指定了无效区域矩形的对角顶点,fErase字段如果为非零值,表示Windows在发送WM_PAINT消息前已经使用背景色擦除了无效区域,后面3个字段是Windows内部使用的,应用程序不必去理会他们。
摘自《Windows环境下32位汇编语言程序设计》
大多数Windows程序在WinMain中进入消息循环之前的初始化期间都要呼叫函数UpdateWindow。Windows利用这个机会给窗口消息处理程序发送第一个WM_PAINT消息。这个消息通知窗口消息处理程序:必须绘制显示区域。此后,窗口消息处理程序应在任何时刻都准备好处理其它WM_PAINT消息,必要的话,甚至重新绘制窗口的整个显示区域。在发生下面几种事件之一时,窗口消息处理程序会接收到一个WM_PAINT消息:
在使用者移动窗口或显示窗口时,窗口中先前被隐藏的区域重新可见。
使用者改变窗口的大小(如果窗口类别样式有着CS_HREDRAW和CS_VREDRAW位旗标的设定)。
程序使用ScrollWindow或ScrollDC函数滚动显示区域的一部分。
程序使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息。