转:ShowWindow与UpdateWindow

在看VC++视频教程的时候,在创建新窗口时对ShowWindow和UpdateWindow有一些疑问,来来回回看了很多遍,自己也调试了几遍,只好求下甚解了。。自己也在csdn发帖求教了(帖子网址:http://topic.csdn.net/u/20100818/23/b30e7e3d-2969-45ec-9054-1e98cca442e5.html)问题描述如下:

查了一些资料,说showwindows是显示窗口,UpdateWindow函数是更新窗口,一般的窗口创建过程大家都知道,如下:
1.设计窗口类
2.注册窗口类
3.ShowWindow()
4.UpdateWindow()
5.消息循环

窗口过程函数里的WM_paint消息就简单地输出一个"test"字符串如下:

case WM_PAINT:
hdc = BeginPaint(hWnd, & ps);
TextOut(hdc, 0, 0 ,L" test ",wcslen(L " test" ));
EndPaint(hWnd, & ps);
break ;

我想问的是:
(1)在ShowWindow()后,为何还要多用一个UpdateWindow(),我在实质测试时把UpdateWindow()删除时运行结果还是一致的。
(2)据查资料,UpdateWindow()函数实质是产生一个WM_PAINT消息,所以在运行程序后,弹出的窗口中就输出了test字符,这个可以理解,但为何把UpdateWindow()函数注释掉,只保留ShowWindow(),程序运行时还是会出现test字符?如果认为是窗口从无到有时产生重绘消息产生的文本,那是否表示在不注释掉UpdateWindow()时已经响应了两次WM_PAINT消息呢?
(3)关于程序运行顺序的问题,按照正常的运行步骤应该是:ShowWindow和UpdateWindow后,进行消息循环里的while (GetMessage( & msg, NULL, 0 ,0 )) 从而将消息取出进行响应,但实质调试时,在UpdateWindow()、while(GetMessage(&msg, NULL, 0, 0))和caseWM_PAINT三处分别设置断点,在调试时,发现实质的运行顺序是UpdateWindow()后直接到caseWM_PAINT,进行了消息响应,再到消息循环的while (GetMessage(&msg,NULL, 0,0)),也就是说UpdateWindow产生WM_PAINT消息后直接就响应了消息,而不是通过这GetMessage()取出再响应的,这点让我很不解

以上是一些疑问,在csdn的帖子里有些高手做了解释,此处我就不复制过来了,可以直接去帖子看,但我在网上搜索了篇非常不错的文章《WM_Paint消息详解》,看后清晰了,原文如下(文章地址:http://www.cnblogs.com/chengxin1982/archive/2009/08/10/1542660.html):

1. 系统何时发送WM_PAINT消息?
转:ShowWindow与UpdateWindow
系统会在多个不同的时机发送 WM_PAINT消息:当第一次创建一个窗口时,当改变窗口的大小时,当把窗口从另一个窗口背后移出时,当最大化或最小化窗口时,等等,这些动作都是由系统管理的,应用只是被动地接收该消息,在消息处理函数中进行绘制操作;大多数的时候应用也需要能够主动引发窗口中的绘制操作,比如当窗口显示的数据改变的时候,这一般是通过 InvalidateRect 和 InvalidateRgn 函数来完成的。

InvalidateRect和 InvalidateRgn把指定的区域加到窗口的 Update Region 中,当应用的消息队列没有其他消息时,如果窗口的Update Region 不为空时,系统就会自动产生 WM_PAINT 消息 。系统为什么不在调用Invalidate 时发送 WM_PAINT 消息呢?又为什么非要等应用消息队列为空时才发送WM_PAINT消息呢?这是因为系统把在窗口中的绘制操作当作一种低优先级的操作,于是尽可能地推后做。

不过这样也有利于提高绘制的效率:两个 WM_PAINT 消息之间通过 InvalidateRect 和InvaliateRgn使之失效的区域就会被累加起来,然后在一个 WM_PAINT 消息中一次得到更新,不仅能避免多次重复地更新同一区域,也优化了应用的更新操作。

这种通过 InvalidateRect 和 InvalidateRgn来使窗口区域无效,依赖于系统在合适的时机发送 WM_PAINT消息的机 制实际上是一种异步工作方式,也就是说,在无效化窗口区域和发送WM_PAINT 消息之间是有延迟的;有时候这种延迟并不是我们希望的,这时我们当然可以在无效化窗口区域后利用SendMessage 发送一条 WM_PAINT消息来强制立即重画,但不如使用 WindowsGDI 为我们提供的更方便和强大的函数: UpdateWindow 和 RedrawWindow。

UpdateWindow 会检查窗口的 Update Region,当其不为空时才发送 WM_PAINT 消息;RedrawWindow 则给我们更多的控制:是否重画非客户区和背景,是否总是发送 WM_PAINT 消息而不管 UpdateRegion 是否为空等。

--------------------------------------------------------------------------------
2. BeginPaint
BeginPaint和 WM_PAINT 消息紧密相关。试一试在 WM_PAINT 处理函数中不写 BeginPaint会怎样?程序会像进入了一个死循环一样达到惊人的CPU占用率,你会发现程序总在处理一个接 一个的 WM_PAINT消息。这是因为在通常情况下,当应用收到 WM_PAINT 消息时,窗口的 Update Region都是非空的(如果为空就不需要发送WM_PAINT 消息了), BeginPaint 的一个作用就是把该 Update Region置为空,这样如果不调用 BeginPaint,窗口的Update Region 就一直不为空,如前所述,系统就会一直发送WM_PAINT 消息。

BeginPaint 和 WM_ERASEBKGND消息也有关系。当窗口的 Update Region 被标志为需要擦除背景时,BeginPaint 会发送 WM_ERASEBKGND消息来重画背景,同时在其返回信息里有一个标志表明窗口背景是否被重画过。当我们用 InvalidateRect 和InvalidateRgn 来把指定区域加到 Update Region 中时,可以设置该区域是否需要被擦除背景,这样下一个BeginPaint 就知道是否需要发送 WM_ERASEBKGND 消息了。

另外要注意的一点是,BeginPaint 只能在 WM_PAINT 处理函数中使用。

看完此文后,头绪也应该清晰了:

(1)单纯一个ShowWindow,照样会正确重画窗口内容,只不过重画是在消息队列取空之后。有时我们希望窗口被立即重画,而不是去等待那个不确定的消息队列,此时就需要用到UpdateWindow。这个函数的作用只有一个:假若当前被标记为重画的区域存在(不存在的话它什么也不做),那么立刻让Windows使用SendMes sage的方式来对你的窗口发送WM_PAINT。

(2)ShowWindow本身是不会产生重画消息的,它的作用仅仅是把窗口显示出来。不过,当窗口显示的时候,Windows会自动探测窗口的内容是否需要重画、以及需要重画的区域组成,比如你的窗口位置直接在屏幕外,或者你的窗口被别的窗口完全挡住,当然就不需要重画,如果你的窗口只露出一部分,那么就只有这一部分需要重画。这个过程与你移动窗口、切换窗口的时候Windows所做的事情是一样的——自动判定你的窗口有哪一部分原来不显示而现在需要显示,然后对这部分区域调用InvalidateRect()。这个函数的作用并不是立刻重画这些区域,而是对这些区域做上标记。多次调用这个函数,新标记的区域会与以前标记的区域合并。因此之前是否产生两个重画消息是错误的,实质只有一个重画消息而已。

(3)关于上面的第三个问题,其实在MSDN中已经有说明了:
The UpdateWindow function updates the client area of the specifiedwindow by sending a WM_PAINT message to the window if the window'supdate region is not empty. Thefunction sends a WM_PAINT message directly to the window procedureof the specified window。

  

爱华网本文地址 » http://www.aihuau.com/a/25101015/238711.html

更多阅读

《超级兄弟:剑与巫术》详尽图文攻略上

极具特色的动作冒险游戏。具有令玩家印象深入的音画效用,设计上走的是剧场路线,而画面作风则是 8-bit 作风。玩家要扮演游览的剑客,历经沿途一路艰难,最终解开月之谩骂成就武士之路。玩家在游戏中可能还需求解开一些音乐的谜题。 《超

电风扇不转,电风扇不转的原因与维修 电风扇不转是什么原因

电风扇简称电扇,在我们日常生活中最常见的电器之一。香港称为风扇,日本及韩国称为扇风机,是一种利用电动机驱动扇叶旋转,来达到使空气加速流通的家用电器,主要用于清凉解暑和流通空气。输配电研究报告显示:广泛用于家庭、办公室、商店、医

今日系列:中国与扎伊尔刚果金 建交日图

今日系列:中国与扎伊尔(刚果金)建交日(图)2月20日,是中华人民共和国与扎伊尔共和国(刚果民主共和国,简称“刚果金”)建交日(1961年)。1960年6月30日,刚果共和国独立。1961年2月19日,中国承认基赞加政府为刚唯一合法政府,2月20日,两国建交。同年9

罗立为:我与焦国标的交往……

【罗立为:我与@焦国标的交往……】2014.8.14.与焦国标在北京延庆“四季花海”……(于浩宸摄)那年中秋时分,我到木樨地寓所拜会@康国雄老先生。康老迎门,济济一堂精英,我座位正对着的红夹克先生,康老介绍:“这是焦国标……”分手时

一年级家庭奥数题:单数与双数

知识要点:1、3、5、7、9…叫做单数,2、4、6、8、10…叫做双数。一个数2个、2个地分,正好分完,这个数就是双数。2个、2个地分完之后,还多1个,这个数就是单数。单数与双数相加、减有如下特点:⑴双数与双数相加、减,结果为双数;⑵单数与单数

声明:《转:ShowWindow与UpdateWindow》为网友忘记了微笑分享!如侵犯到您的合法权益请联系我们删除