2010-02-05 55 views
0

我有以下窗口层次结构的应用程序:即使在调用UpdateWindow()后,为什么paint消息会丢失?

W1 
    -W2 (Child of W1) 
    - W3 (Child of W2) 

--------------------| 
| W1|------------| | 
| |W2 |------| | | 
| | |W3 | | | 
| | |------| | | 
| |------------| | 
|-------------------| 

当某个事件在W2发生时,我打电话UpdateWindow

W2::onCertainEvent() 
{ 
     Invalidate(NULL); 
     UpdateWindow(); 
} 

OnPaint处理W2的是这样的:

W2::onPaint() 
    { 
    //W2 logic goes here 
    W3.Invalidate(NULL); //So that paint messages are given to W3 
    } 

但有些时候油漆信息在W2中迷路了。尽管UpdateWindow被调用,但没有相应的OnPaint()被调用。

如果我将属性WS_EX_TRANSPARENT添加到W1(W2的父级),则总是在@ W2处收到绘制消息。

但添加WS_EX_TRANSPARENT标志的问题是,当我调整窗口W1的大小时,它会产生大量的闪烁。

我的问题是: 1. W2中出现什么问题,Paint消息会丢失? 2.为什么添加WS_EX_TRANSPARENT解决了Paint问题。 3.如果使用标志,我该如何解决闪烁问题。

感谢,

回答

2

闪烁
闪烁可以通过发放WM_ERASEBKGND,并确保它不执行任何操作来解决。闪烁可能发生,因为每个窗口在每次绘制之前都会处理此消息,以使用其背景颜色擦除无效区域。如果您处理它并且什么都不做,那么擦除不会发生 - 只要确保您的WM_PAINT处理程序绘制了整个无效区域,否则您将留下之前绘制的绘制物。

然而,在这种情况下,我认为闪烁的发生是因为W1先画自己,然后是W2,然后是W3画在每个画图上。这表明WS_EX_TRANSPARENT不是解决您遇到的问题的方法。

Missing WM_PAINT
很难知道如何跟踪这种情况。在.NET中,发生这种情况的原因是子窗口隐藏了控件的整个客户区域,因此不会传播绘制消息,但我相信这是特定的.NET行为。如果你可以提供一个示例项目或示例代码来展示这个问题,那将是一个很大的帮助。

与此同时,您可以删除W3,以便W2不被遮挡,并查看是否所有的消息都返回。另请注意,CWnd::Invalidate不会将NULL作为选项,它需要BOOLTRUEFALSE)。

2

WM_PAINT“消息”并不是真正意义上的消息。它们的行为与每个窗口消息队列末尾的标志非常相似。他们不通过线程消息队列,他们没有在Windows消息队列中的位置。当您尝试从Windows消息队列中检索消息时会生成它们,并且没有其他消息。那时候,所有不同的失效都会被考虑,并且会生成一个或多个(!)WM_PAINT。

结果是在W2::onCertainEvent()之后,将设置“窗口无效”标志。因此,最终WM_PAINT将被调用,但生成的WM_PAINT不会专门用于该“某些事件”。

历史背景是,如果有很多待处理的消息,您不想花太多时间来绘制窗口,因为这些可能只会使窗口无效。最好先让你的模型更新,然后做视图的东西。

相关问题