我有一个具有以下Windows层次结构的应用程序:

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

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


当W2中发生某些事件时,我呼叫UpdateWindow

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


W2的OnPaint处理如下所示:

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


但是有时在W2中迷失了绘画信息。尽管UpdateWindow被调用,但没有相应的OnPaint()被调用。

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

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

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

谢谢,

最佳答案

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

但是,在这种情况下,我相信会发生闪烁,因为W1会先绘制自身,然后再绘制W2,然后再绘制W3。这表明WS_EX_TRANSPARENT不能解决您遇到的问题。

缺少WM_PAINT
很难知道如何进行追踪。在.NET中,发生这种情况是因为子窗口遮盖了控件的整个客户端区域,因此绘制消息不会通过传播,但是我相信这是特定的.NET行为。如果您可以提供一个示例项目或示例代码来解决问题,那将是一个很大的帮助。

同时,您可以删除W3,以便不会遮挡W2,然后查看是否所有的绘制消息都返回了。另外,请注意,CWnd::Invalidate不会将NULL作为选项,而是会使用BOOLTRUEFALSE)。

关于c++ - 为什么即使调用UpdateWindow()后绘画消息也会丢失?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2207433/

10-11 01:30