关于win32 sdk 窗口重画的问题

各位大师好。刚学win32api有点疑问;就是::GetClientRect(hwnd,&rect);::InvalidateRect(hwnd,&rect,true);... 各位大师好。刚学win32 api有点疑问;

就是

::GetClientRect(hwnd,&rect);

::InvalidateRect(hwnd,&rect,true);

这两句话不是会给程序发送WM_PAINT消息吗,我知道这个PAINT是不会立即执行的,因为有优先级。

所以在后面要强制WM_PAINT的话就加了一句:

::UpdateWindow(hwnd);

这句话就可以直接立即重画窗口了。

但是我的疑问是

为什么直接::UpdateWindow(hwnd)就不能达到窗口重画的效果呢?

msdn上说UpdateWindow的执行条件是客户区不为空,但是我的客户区明明是有东西呀..(至少有几条线或者图形),只调用UpdateWindow的时候为什么就不重画呢?

偏偏要加上:

::GetClientRect(hwnd,&rect);

::InvalidateRect(hwnd,&rect,true);
展开
 我来答
Frank7258
推荐于2016-03-02 · TA获得超过1503个赞
知道小有建树答主
回答量:381
采纳率:0%
帮助的人:547万
展开全部
你理解错了msdn的话了,WM_PAINT会发送的条件不是“客户去不为空”,而是失效区域不为空!
这个区域就是你标记的或者是Winodws标记为失效的区域,失效的意思是这个区域内的内容已经不正确了,取消重新绘制。

你如何设置失效区域:调用InvalidateRect,另外,如果你要设置整个客户区都失效:
InvalidateRect(hWnd, NULL, TRUE); 不必调用GetClientRect。

何时Windows会自动设置失效区域?比如,你的窗口被其他窗口遮挡,如果此时用户把你的程序激活到前台,Windows自动设置刚才遮挡的部分为失效区域。以便在随后的WM_PAINT的时候这个区域会擦除之前的内容(之前的内容其实是另一个窗口的内容),画上自己窗口的内容。如果你的程序从最小化还原,整个客户去都会被Windows自动设置为失效区域。不过,鼠标滑过窗孔不会导致Windows自动设置失效区域,鼠标滑过在Windows中有特别处理,不需要程序员自己来操心。

只有当这个失效区域不为空的时候WM_PAINT才会被发送!而函数UpdateWindow的实质就是发送WM_PAINT,因而你如果不指定InvalidateRect则通过UpdateWindow不会更新窗口(确切的说是不一定会更新窗口,取决于Windows是否为你自动设置了失效区域)。

另外,Windows出于程序运行效率的考虑,在画图的时候,只有在失效区域的内容会被更新到屏幕上,如果你画了一个物体,在失效区域以外,那么这些语句直接会被Windows忽略。所以,正确设置失效区域是相当重要的,比如你写一个程序,有一个正方形,一个圆形,如果你这时候改变正方形的颜色,只要把这个正方形设置为失效区域即可。虽然你在响应WM_PAINT的时候同时也画了这个圆形,但是圆形由于不再失效区域,这些代码对Windows来说就相当于走了个过场,实际上没有操作显存。简单的程序,你偷懒直接设置全部客户去失效是可行的,但是如果你的WM_PAINT响应非常复杂,那么你不合理设置失效区域会导致程序界面闪烁,响应缓慢等问题。
追问
回答的很专业,邮箱:daoluanxiaozi@126.com,希望能跟你一起学习。(收到邮件后采纳)
何处淬吴钩
2011-09-03 · TA获得超过5043个赞
知道大有可为答主
回答量:2947
采纳率:50%
帮助的人:2376万
展开全部
UpdateWindow在窗口有变化时重绘,无变化就没必要重绘了。就跟你在word中点完保存不做任何修改再点保存没什么变化一样。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
江小右
2011-09-05 · TA获得超过6928个赞
知道小有建树答主
回答量:1195
采纳率:0%
帮助的人:818万
展开全部
1:设置无效区
InvalidateRect

2:立即刷新
UpdateWindow();

如果只有2的话并没有设置过无效区域,结合你自己的理解再想想
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
skyscar1307
2011-09-03 · 超过15用户采纳过TA的回答
知道答主
回答量:99
采纳率:0%
帮助的人:52.4万
展开全部
UpdateWIndow执行的条件是客户区不为空。
这里的客户区指的不是你那儿有什么东西,
而是通过GetClientRect取得的客户区,
然后通过InvalidateRect使得取得的客户区失效,
这样等到响应WM_PAINT时,才会重绘。

重绘是因为需要重绘,例如你移动了窗口,或者你的窗口被别的窗口挡着了,
如果窗口好好的在哪儿,什么都没有变,为什么要重绘
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式