WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)
什么时候会触发WM_PAINT消息消息呢?
以下内容来自大名鼎鼎的《Windows程序设计(第五版)》
大多数Windows程序在WinMain中进入消息循环之前的初始化期间都要呼叫函数UpdateWindow。Windows利用这个机会给窗口消息处理程序发送第一个WM_PAINT消息。这个消息通知窗口消息处理程序:必须绘制显示区域。此后,窗口消息处理程序应在任何时刻都准备好处理其它WM_PAINT消息,必要的话,甚至重新绘制窗口的整个显示区域。在发生下面几种事件之一时,窗口消息处理程序会接收到一个WM_PAINT消息:
- 在使用者移动窗口或显示窗口时,窗口中先前被隐藏的区域重新可见。
- 使用者改变窗口的大小(如果窗口类别样式有着CS_HREDRAW和CS_VREDRAW位旗标的设定)。
- 程序使用ScrollWindow或ScrollDC函数滚动显示区域的一部分。
- 程序使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息。
在某些情况下,显示区域的一部分被临时覆盖,Windows试图保存一个显示区域,并在以后恢复它,但这不一定能成功。在以下情况下,Windows可能发送WM_PAINT消息:
- Windows擦除覆盖了部分窗口的对话框或消息框。
- 菜单下拉出来,然后被释放。
- 显示工具提示消息。
在某些情况下,Windows总是保存它所覆盖的显示区域,然后恢复它。这些情况是:
- 鼠标光标穿越显示区域。
- 图标拖过显示区域。
但实际上,在win7下编写的程序,有可能遇到下面的情况:
当把程序窗口最大化时,触发WM_PAINT消息;当移动窗口时,有时会触发WM_PAINT消息,有时不会触发;而当其他窗口遮挡程序的窗口时,一定不会发出WM_PAINT消息,这又是为什么呢?
其实这跟你的windows7的设置有关,在“控制面板”的“性能信息和工具”一栏中,选择“调整视觉效果”,将“启用桌面组合”去掉,就可以了。
当触发WM_PAINT消息时,就会准备处理整个区域。可实际上,系统只是重绘无效区。比如,当你把窗口A从窗口B上移开时,不是整个重绘窗口B,而是,B的其他部分不动,只是重绘漏出来的部分。要是你想整个重绘,需要使用InvalidateRect (hwnd, NULL, TRUE)指明无效区是整个客户区。
那么WM_PAINT消息该如何使用呢?
windows绘图,是通过GDI(图形设备接口)完成。简单的说,GDI是由:DC(设备描述表),GDI函数,GDI基本图形和一些其他的东西组成的。要想使用GDI绘图,必须拿到DC。因为DC与特定的显示(打印设备相关)。只有拿到了DC,才能正确的输出图形。举一个简单的例子,光栅设备(简单的说,就是显示的时候以像素为单位的)和矢量设备(显示的时候,告诉他起点和终点,它会给你自动连线的)的成像原理不同,所以只有知道了他们的成像原理(DC里面有),才能画图。
那么怎么拿到DC呢,方法很多,但是在WM_PAINT消息下,只能使用BeginPaint获取hdc,用完之后使用EndPaint释放它。在二者之间写GDI函数。即使你在WM_PAINT消息下什么都不做,也得写上这两句。原因是因为WM_PAINT会导致无效区域的背景被擦除。
http://blog.csdn.net/thefutureisour/article/details/7533497
WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)的更多相关文章
- spy++ 句柄消息详解
使用spy++捕获到的消息详解 主要是今天正好自己用到. 原来也有用过SPY++查看消息,然后自己SendMessage或者PostMessage 直接发送消息给目标程序.但是原来一用就有效果,今天要 ...
- 举例详解Python中的split()函数的使用方法
这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:sp ...
- MFC消息详解 (WindowProc|OnCommand|OnNotify)
1. 怎样使用MFC发送一个消息用MFC发送一个消息的方法是, 首先,应获取接收消息的CWnd类对象的指针: 然后,调用CWnd的成员函数SendMessage( ). LRESULT Res=pWn ...
- RabbitMQ中Confirm确认与Return返回消息详解(八)
理解Confirm消息确认机制: 消息的确认,是指生产者投递消息后,如果Broker收到消息,则会给我们生产这一个应答. 生产者进行接收应答,用来确定这条消息是否正常的发送到Broker,这种方式也是 ...
- oracle分析函数技术详解(配上开窗函数over())
一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...
- 详解php 获取文件名basename()函数的用法
PHP 中basename()函数给出一个包含有指向一个文件的全路径的字符串,此函数返回基本的文件名,本篇文章收集了关于使用PHP basename()函数获取文件名的几篇文章,希望对大家理解使用PH ...
- Web Service学习之八:Soap消息详解
一.区别概念 WSDL是网络服务描述语言,是XML文档:它包含一系列描述某个web service的定义或者说是规则.尤其是定义了传输Sope消息的结构 Soap:简单对象访问协议,是交换数据的一种协 ...
- 微信小程序模板消息详解
先放代码 wxml: <form name='pushMsgFm' report-submit bindsubmit='orderSign'> <view> 单号: 0< ...
- sql server 函数详解(5)系统函数
返回表中指定字段的长度 返回表中指定字段的名称 返回数据表达式的数据的实际长度函数 返回数据库的编号 返回数据库的名称 返回数据库当前默认的null值 返回服务器端计算机的标识号 返回服务 ...
随机推荐
- Oracle中的EXCEPTION
Oracle系统预定义的异常 比如:SELF_IS_NULL.VALUE_ERROR.ZERO_DIVIDE等Oracle中自带的异常类型 使用方法: DECLARE V_Result ); BEGI ...
- C++堆和栈的比较(7个区别)
基础知识: 堆 栈是一种简单的数据结构,是一种只允许在其一端进行插入或删除的线性表.允许插入或删除操作的一端称为栈顶,另一端称为栈底,对堆栈的插入和删除操作被称 为入栈和出栈.有一组CPU指令可以实现 ...
- 字符编码终极笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian
1.字符编码.内码,顺带介绍汉字编码 字符必须编码后才能被计算机处理.计算机使用的缺省编码方式就是计算机的内码.早期的计算机使用7位的ASCII编码,为了处理汉字,程序员设计了用于简体中文的GB231 ...
- IT第二天 - JAVA环境的配置、Hello的编写
IT第二天 上午 HTML的一些讲解 下午 JDK的安配置 JAVA语法的注意事项 Hello的编写 晚上 作业 对println的应用 笔记 1.Classpath环境变量的配置:因为DOS对于文件 ...
- Java集合中对象排序
集合中的对象排序需求还是比較常见的.当然我们能够重写equals方法,循环比較:同一时候Java为我们提供了更易使用的APIs.当须要排序的集合或数组不是单纯的数字型时,通常能够使用Comparato ...
- IBATIS动态SQL
转自:http://www.cnblogs.com/phoebus0501/archive/2011/05/16/2048126.html 直接使用JDBC一个非常普遍的问题就是动态SQL.使用参数值 ...
- PHP - 直接输出对象的版本问题
- ios8.1上运行程序,程序界面只显示一部分
在ios 9.1上运行程序没问题 但是在8.1上运行发现模拟器上只显示了程序的一小部分界面,没有显示完全. 结果发现由以下代码设置问题引起的 - (BOOL)application:(UIApplic ...
- html的头部标签详解
<!DOCTYPE html> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &q ...
- 轻量级数据库sqlite的编译
sqlite是很多客户端程序所使用的一种轻量级数据库,但是目前没有lib文件,只有源码和dll文件,我们可以利用VS工具生成lib,然后在应用程序中使用. (1)下载地址 http://www.sql ...