VC++中的invalidate和update方法是什么?

8
我对C++中的窗口函数有一些疑问。 "invalidate()"函数具体是做什么的? 它发送了什么消息?我们需要在什么时候调用它?还有"update()"函数是什么? "invalidaterect()"函数是否与"invalidate()"函数类似?
谢谢。
2个回答

10
CWnd::Invalidate()函数使窗口的整个客户区无效,表示该区域已经过时,需要重新绘制。通常在需要重绘的控件上调用此函数。CWnd::InvalidateRect()函数只会使窗口的一部分无效。
使用Invalidate函数,WM_PAINT消息将被发送到消息队列中,并在未来某个时间处理。使用CWnd::UpdateWindow()函数发送(而不是发送)WM_PAINT消息,导致无效的区域立即被重绘。
这些内容都可以在文档中找到。

4
没错。不需要同时调用两者。通常只有在同一线程之后会进行一些耗时计算的情况下,才会调用 UpdateWindow,这样它就不能很快地回到消息循环中。在这种情况下,您希望立即重绘,而不是等到更方便的时间再重绘。但一般情况下,请使用 Invalidate - Thomas
4
实际上,“WM_PAINT”消息并没有被发布。窗口管理器只是设置了一个内部标志,并且该标志由消息泵中的“::Peek/GetMessage”检查。如果已设置标志并且队列中没有更高优先级的消息,则“WM_PAINT”将在“MSG”结构中返回。 - Johann Gerell
@JohannGerell 谢谢。那么“post”和“set flag”的区别是什么? - starriet
1
“发布”消息意味着将消息放入消息队列中,以便稍后通过get/peek消息进行检索,并由窗口过程进行处理。 “发送”消息意味着立即调用带有消息的窗口过程。 在此上下文中设置标志(flag)意味着当用户调用Win32 API之一使窗口无效时,窗口管理器会设置一个标志“the_window_is_invalidated”。当所有已发布的高优先级消息都被处理后,如果发现该标志已设置,则在下次调用get/peek消息时,窗口管理器将返回WM_PAINT消息。 - Johann Gerell
2
@starriet 了解为什么要这样做可能会有所帮助。队列中的其他消息(例如用户输入)通常会导致更多的失效。如果 WM_PAINT 像其他消息一样被发布或发送,程序通常会花费时间绘制那些在绘制期间或之前入队的消息后立即变得过时的区域。通过设置标志,Windows 确保消息队列为空,因此程序已达到“稳定状态”,任何绘制都不太可能是浪费的努力。 - Thomas
显示剩余4条评论

2
invalidate函数将绘图区标记为无效。当窗口被重新绘制时,如果该区域被标记为无效,则会重新绘制该区域;否则,它将保持屏幕区域不变。invalidate函数使给定对象的整个客户区域无效,invalidaterect函数使特定客户区域无效。update函数执行实际的重绘操作。
这种机制之所以存在,而不是在知道某些内容需要更改时立即绘制,是因为可以防止多次重绘,例如,您一次性接收到三个按键消息,滚动某个文本区域。如果您为每个按键事件都重新绘制文本区域,则必须三次绘制文本区域,应用程序将变得不响应。相反,在重绘文本区域之前,处理所有按键事件,更新附加到文本区域的数据结构并使文本区域无效,然后只需重绘文本区域一次。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接