2011-11-30 75 views
1

在Windows上,當我顯示一個對話框(自定義對話框或標準打開/保存文件對話框)並將對話框移到父窗口上方時,父窗口不會重繪,從而留下對話框的痕跡被拖拽後面。 (父窗口使用OpenGL繪製,但不確定這是相關的。)如何在主窗口移動時重新繪製主窗口?如何在對話框移動後重新繪製對話框窗口?

我試圖添加一個調用來重繪我的主窗口,每當對話框的回調被髮送一條消息,但這隻會導致重繪發生,無論何時按下按鈕或編輯字段鍵入英寸它不重繪時,對話框的窗口被移動。我如何檢測這個動作?

+1

「(父窗口使用OpenGL繪製,但不確定這是相關的。)」 - 這**是**相關的。你需要使渲染上下文無效 - 自從我做這些事情以來,我一直在挖掘它。 – ChrisF

+3

Windows向該窗口發送WM_PAINT消息以告訴其重繪本身。不要忽視它們。 –

回答

1

我懷疑你的opengl應用程序只是使用一個窗口來顯示通過opengl渲染的目的,然後進入一個緊密的循環檢查鼠標/ kb輸入,然後重新繪製opengl表面。我猜你畫的畫框後不會抽出信息。更重要的是,你爲窗口設置的那個小存根WndProc可能沒有WM_PAINT處理函數。

兩件事情要考慮。您的主窗口的WndProc需要捕獲WM_PAINT,重繪和驗證曲面。也就是說....

LRESULT __stdcall YourMainWndProcHandler(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (uMsg) 
    { 
     ... 
     case WM_PAINT: 
     { 
      PAINTSTRUCT ps; 
      BeginPaint(hwnd, &ps); 
      EndPaint(hwnd, &ps); 
      // redraw your stuff here 
      return 0; 
     } 
     ... 
    } 
} 

調用BeginPaint/EndPaint函數來處理WM_APINT上面,你可以很可能只是調用ValidateRect代替。

最好是,您正在捕捉循環中的其他窗口消息。這樣,如果一個窗口被你的應用程序之外的其他東西遮擋(例如調整大小操作,最小化/恢復,其他Windows應用程序需要前景等),那麼你也可以處理重繪通知。

一個典型的遊戲試圖每個繪圖框架泵送1條消息。

void MainLoop() 
{ 
    MSG msg; 
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    // your code to simulate and render below 
    DrawScreen(); 
} 
+0

謝謝。我實際上使用的是SDL 1.3,現在我的猜測是,當它從Windows獲取WM_PAINT事件時,SDL 1.3不會傳遞窗口重繪事件。可能這是SDL中的一個錯誤,需要修復。我會仔細看看的。 –

+0

儘管上面的回覆有一個問題。我使用的對話框是模態的,所以它們在退出之前不會返回控制權。在這種情況下,我看不出我的遊戲的主要事件循環是如何相關的? –

+0

我對此進行了深入研究,SDL在收到WM_PAINT事件時向我發送了SDL_WINDOWEVENT_EXPOSED事件。但是,只有當我的窗口位於後臺時,纔會獲得這些事件,而其他應用程序的窗口位於前面並且正在拖動。當我自己的對話框(模態)被拖動時,我不會收到這些事件。這裏唯一的解決方案是使用無模式對話框嗎?如果是這樣,那麼標準的打開/保存對話框的解決方案是什麼? –