The River is Just a River  
If you're absent from my struggle,then,don't be present for my success

在创建一个windows应用程序时,在创建窗口的部分一般会有如下的函数调用:

CreateWindow(...) ;
ShowWindow(...) ;
UpdateWindow(...) ;

第一句:创建窗口

第二句:显示窗口(显示创建之后的窗口)

第三句:对窗口进行绘画


现在来探讨一下UpdateWindow函数,下面是MSDN上的解释:

UpdateWindow sends a WM_PAINT message directly to the window procedure of the specified window, bypassing the application queue. 

 

 下面我们创建一个windows应用程序,在WndProc函数中的WM_PAINT的第一句话处设置断点,如下图:

然后点击F5,进入调试,查看“调用堆栈”的信息,如下图所示:

我是使用VS2010创建的应用程序,UpdateWindow函数是在InitInstance()函数中调用的,上图所示:从下到上是堆栈的调用过程,我们可以看出,从IninInstance函数直接到了WndProc函数,也就是说当我们调用了UpdateWindow后,并没有返回到主函数进入消息循环,而是直接调用了WndProc过程处理WM_PAINT消息。

 

我们再考虑另一个函数InvalidateRect,同样看一下MSDN的解释:

This function adds a rectangle to the specified window's update region. The update region represents the portion of the window's client area that must be redrawn.

If the second parameter is NULL, the entire client area is added to the update region. 

现在,将InitInstance中的UpdateWindwo(hwnd)变为InvalidateRect(hwnd,NULL,TRUE),同样是设置断点,观察调用堆栈的信息,如下:

其实这个调用过程是这样的:winmain调用InitInstance函数,InitInstance函数结束并没有像UpdateWindow那样直接调用WndProc,而是返回到WinMain函数,因为InvalidateRect已经将整个窗口设为无效(the update region is not empty),而只要the update region is not empty,那么windows就会发送一个WM_PAINT消息,被WinMain的消息循环接收(只有InitInstance函数返回后才会进入消息循环),进而去调用WndProc函数处理消息。


简单的说:UpdateWindow会立即使窗口重画,而InvalidateRect将使WM_PAINT进入消息队列,然后依次处理。

posted on 2012-08-23 13:54  TiffanyZhou  阅读(1503)  评论(3编辑  收藏  举报