三、Windows编程之滚动条—绘图程序的组织

在处理完滚动条消息后,SYSMETS2不更新显示区域,相反,它呼叫InvalidateRect使显示区域失效。这导致Windows将一个WM_PAINT消息放入消息队列中。

最好能使Windows程序在响应WM_PAINT消息时完成所有的显示区域绘制功能。因为程序必须在一接收到WM_PAINT消息时就更新整个显示区域,如果在程序的其它部分也绘制的话,将很可能使程序代码重复。

首先,您可能对这种拐弯抹角的方式感到厌烦。在Windows的早期,因为这种方式与文字模式的程序设计差别太大,程序写作者感到这种概念很难理解。并且,程序要不断地通过马上绘制画面来响应键盘和鼠标。这样做既方便又有效,但是在很多情况下,这完全不必要。当您掌握了在响应WM_PAINT消息时积累绘制显示区域所需要的全部信息的原则之后,会对这种结果感到满意的。

如同SYSMETS2示范的,程序仍然需要在处理非WM_PAINT消息时更新特定的显示区域,使用InvalidateRect就很方便,您可以用它使显示区域内的特定矩形或者整个显示区域失效。

只将窗口显示区域标记为无效以产生WM_PAINT消息,对于某些应用程序来说也许不是完全令人满意的选择。在呼叫InvalidateRect之后,Windows将WM_PAINT消息放入消息队列中,最后由窗口消息处理程序处理它。然而,Windows将WM_PAINT消息当成低优先级消息,如果系统有许多其它的动作正在发生,那么也许会让您等待一会儿工夫。这时,当对话框消失时,将会出现一些空白的「洞」,程序仍然等待更新它的窗口。

如果您希望立即更新无效区域,可以在呼叫InvalidateRect之后呼叫UpdateWindow:

UpdateWindow (hwnd) ;
        

如果显示区域的任一部分无效,则UpdateWindow将导致Windows用WM_PAINT消息呼叫窗口消息处理程序(如果整个显示区域有效,则不呼叫窗口消息处理程序)。这一WM_PAINT消息不进入消息队列,直接由Windows呼叫窗口消息处理程序。窗口消息处理程序完成更新后立即退出,Windows将控制传回给程序中UpdateWindow呼叫之后的叙述。

您可能注意到,UpdateWindow与WinMain中用来产生第一个WM_PAINT消息的函数相同。最初建立窗口时,整个显示区域内容变为无效,UpdateWindow指示窗口消息处理程序绘制显示区域。