代码之家  ›  专栏  ›  技术社区  ›  aJ.

为什么在调用updatewindow()之后绘制消息会丢失?

  •  0
  • aJ.  · 技术社区  · 14 年前

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

    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中,绘画信息会丢失。虽然 更新窗口 被调用,没有对应的 窗体重画 (一)接到电话。

    如果我添加一个属性 WS_EX_TRANSPARENT 到w1(w2的父级),则始终在w2接收到绘画消息。

    但是添加 透明的 标志是当我调整窗口w1的大小时,它会产生很多闪烁。

    我的问题是: 1。w2中有什么问题导致绘画信息丢失? 2。为什么添加 透明的 解决油漆问题。 三.如果使用了标志,如何解决闪烁问题。

    谢谢,

    2 回复  |  直到 14 年前
        1
  •  2
  •   Jeff Yates    14 年前

    闪烁
    闪烁可以通过处理 WM_ERASEBKGND 确保它什么都不做。闪烁可能发生,因为每个窗口在每次绘制之前处理此消息,以使用其背景色擦除无效区域。如果你处理它什么也不做,就不会发生擦除-只要确保 WM_PAINT 处理程序将绘制整个无效区域,否则将留下以前绘制的工件。

    但是,在这种情况下,我相信闪烁的发生是因为w1先在每个绘制上绘制自己,然后w2,然后w3。这表明 WS_EX_TRANSPARENT 不是解决问题的方法。

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

    同时,您可以删除w3,这样w2就不会被遮挡,并查看是否所有的绘画消息都返回。另外,请注意 CWnd::Invalidate 不接受null作为选项,它接受 BOOL ( TRUE FALSE )

        2
  •  2
  •   MSalters    14 年前

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

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

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