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

时间: 2024-10-11 23:41:22

WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)的相关文章

jQuery选择器代码详解(七)——elementMatcher函数

要读懂Sizzle的Compile执行过程,首先需要弄清楚涉及的各个子程序的功能和关键变量和作用,我将逐一对jQuery-1.10.2版本的Compile代码进行说明,望能给予大家帮助. elementMatcher(matchers) 1.源码 function elementMatcher(matchers) { return matchers.length > 1 ? function(elem, context, xml) { var i = matchers.length; while

jQuery选择器代码详解(八)——addCombinator函数

function addCombinator(matcher, combinator, base) 1.源码 function addCombinator(matcher, combinator, base) { var dir = combinator.dir, checkNonElements = base && dir === "parentNode", doneName = done++; return combinator.first ? // Check a

举例详解Python中的split()函数的使用方法

这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:split() Python中有split()和os.path.split()两个函数,具体作用如下:split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list)os.path.split():按照路径将文件名和路径分割开 一.函数说明1.split()函数语法:str.

详解微信开发者文档——3接收用户文本消息并自动回复文本消息

写在前面的话:上一篇介绍了如何将自己的服务器与微信公众平台进行连接,连接成功之后就可以与微信进行交互了,这一篇介绍最简单的情形,接收用户文本消息,并自动回复文本消息,如果能够实现这个功能,那么我们就能够轻松的实现接收不同的用户消息,并根据业务需要回复用户不同类型的消息,更复杂的在下一篇中讲解. =====正文开始===== 当微信用户向公众号发送消息时,微信服务器会将该消息发送至我们填写的URL中,我们在后台就能够写代码实现接收消息---处理消息----回复消息的操作. 这里有几点需要注意: 1

http标头详解/即php中header函数应用解释

HTTP协议header标头详解 分类: Webkit Web Php C/C++ 2012-10-31 11:19 14366人阅读 评论(0) 收藏 举报 本文根据RFC2616(HTTP/1.1规范),参考 http://www.w3.org/Protocols/rfc2068/rfc2068 http://www.w3.org/Protocols/rfc2616/rfc2616 http://www.ietf.org/rfc/rfc3229.txt 通常HTTP消息包括客户机向服务器的请

详解php 获取文件名basename()函数的用法

PHP 中basename()函数给出一个包含有指向一个文件的全路径的字符串,此函数返回基本的文件名,本篇文章收集了关于使用PHP basename()函数获取文件名的几篇文章,希望对大家理解使用PHP basename()函数获取文件名有所帮助. 1.详解php basename()函数获取文件名的用法 php basename()函数给出一个包含有指向一个文件的全路径的字符串,本函数返回基本的文件名.如果文件名是以 suffix 结束的,那这一部分也会被去掉.在 Windows 中,斜线(/

oracle分析函数技术详解(配上开窗函数over())

一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值. 分析函数和聚合函数的不同之处是什么?普通的聚合函数用group by分组,每个分组返回一个统计值,而分析函数采用partition by分组,并且每组每行都可以返回一个统计值. 分析函数的形式分析函数带有一个开窗函数over(),包含三个分析子句:分组(partition by), 排序(or

详解Python中的join()函数的用法

函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下:     join():    连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串     os.path.join():  将多个路径组合后返回 一.函数说明 1.join()函数 语法:  'sep'.join(seq) 参数说明 sep:分隔符.可以为空 seq:要连接的元素序列.字符串.元组.字典 上面的语法即:以sep作为分隔符,将s

jQuery动画高级用法——详解animation中的.queue()函数

http://www.cnblogs.com/zhwl/p/4328279.html $('#object').hide('slow').queue(function(next){     $(this).appendTo($('#goal'));     next(); }).show('slow'); $('div').slideUp('slow').slideDown('slow',function(){     $('#object').css({"background":&q