2010-02-05 57 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不會專門用於該「某些事件」。

歷史背景是,如果有很多待處理的消息,您不想花太多時間來繪製窗口,因爲這些可能只會使窗口無效。最好先讓你的模型更新,然後做視圖的東西。

相關問題