在Windows上,當我顯示一個對話框(自定義對話框或標準打開/保存文件對話框)並將對話框移到父窗口上方時,父窗口不會重繪,從而留下對話框的痕跡被拖拽後面。 (父窗口使用OpenGL繪製,但不確定這是相關的。)如何在主窗口移動時重新繪製主窗口?如何在對話框移動後重新繪製對話框窗口?
我試圖添加一個調用來重繪我的主窗口,每當對話框的回調被髮送一條消息,但這隻會導致重繪發生,無論何時按下按鈕或編輯字段鍵入英寸它不重繪時,對話框的窗口被移動。我如何檢測這個動作?
在Windows上,當我顯示一個對話框(自定義對話框或標準打開/保存文件對話框)並將對話框移到父窗口上方時,父窗口不會重繪,從而留下對話框的痕跡被拖拽後面。 (父窗口使用OpenGL繪製,但不確定這是相關的。)如何在主窗口移動時重新繪製主窗口?如何在對話框移動後重新繪製對話框窗口?
我試圖添加一個調用來重繪我的主窗口,每當對話框的回調被髮送一條消息,但這隻會導致重繪發生,無論何時按下按鈕或編輯字段鍵入英寸它不重繪時,對話框的窗口被移動。我如何檢測這個動作?
我懷疑你的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();
}
謝謝。我實際上使用的是SDL 1.3,現在我的猜測是,當它從Windows獲取WM_PAINT事件時,SDL 1.3不會傳遞窗口重繪事件。可能這是SDL中的一個錯誤,需要修復。我會仔細看看的。 –
儘管上面的回覆有一個問題。我使用的對話框是模態的,所以它們在退出之前不會返回控制權。在這種情況下,我看不出我的遊戲的主要事件循環是如何相關的? –
我對此進行了深入研究,SDL在收到WM_PAINT事件時向我發送了SDL_WINDOWEVENT_EXPOSED事件。但是,只有當我的窗口位於後臺時,纔會獲得這些事件,而其他應用程序的窗口位於前面並且正在拖動。當我自己的對話框(模態)被拖動時,我不會收到這些事件。這裏唯一的解決方案是使用無模式對話框嗎?如果是這樣,那麼標準的打開/保存對話框的解決方案是什麼? –
「(父窗口使用OpenGL繪製,但不確定這是相關的。)」 - 這**是**相關的。你需要使渲染上下文無效 - 自從我做這些事情以來,我一直在挖掘它。 – ChrisF
Windows向該窗口發送WM_PAINT消息以告訴其重繪本身。不要忽視它們。 –