Очистка экрана после переключения из полноэкранного режима? - PullRequest
2 голосов
/ 27 августа 2011

Итак, у меня запущено приложение OpenGL, которое может переключаться между полноэкранным режимом и оконным режимом.В настоящее время он делает это, изменяя размеры окна и изменяя стили.

Однако, по-видимому, он не делает экран недействительным при переключении из полноэкранного режима в оконный режим, в результате чего вещи, которые я нарисовал, остаются на экране после переключения.Интересно, что это проявляется только в режиме одного монитора.Если я работаю с несколькими мониторами, это делает недействительным все в порядке и очищает мой чертеж.

Я не думаю, что это ошибка драйвера, так как это происходит на двух разных компьютерах с использованием двух отдельных видеокарт (хотя по общему признаниюони оба nVidia.), я думаю, что-то делаю что-то не так.

Я попробовал несколько способов заставить Windows очистить экран от моих ранее полноэкранных рисунков, но, похоже, ничего не происходитРабота.InvalidateRect (), RedrawWindow (), ChangeDisplaySettings () ... В частности:

InvalidateRect(m_hwnd, &rectx, true); // rect being the dimensions of either the screen or my window.
InvalidateRect(HWND_DESKTOP, NULL, TRUE); // Doesn't seem to do anything.
RedrawWindow(NULL, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW);
ChangeDisplaySettings(NULL, 0);

Ну, на самом деле, одна вещь, которая действительно работает, это ShowWindow (hwnd, SW_HIDE) перед изменением размера.Однако это на мгновение теряет фокус, позволяя другим приложениям захватывать входные данные моего приложения, и кажется плохим способом сделать это.Я должен отметить, что я не делаю никаких реальных изменений режима отображения, когда я вижу это поведение;просто оставаясь в текущем разрешении для полноэкранного режима.

Я немного не понимаю, где я иду не так.Упрощенный код:

if(m_isFullscreen)
{
    ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
}
else
{
    ChangeDisplaySettings(&m_dmSavedScreenSettings, 0);
}
if(m_isFullscreen)
{
    dwExStyle = WS_EX_APPWINDOW;
    dwStyle = WS_POPUP;
    ShowCursor(false);
}
else
{
    dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
    dwStyle = WS_OVERLAPPEDWINDOW;
    if(m_isRunning) // Because ShowCursor uses a counter to indicate, and windowed mode defaults to cursor on, we don't need to increment the counter and double it being on.
    {
        ShowCursor(true);
    }
}

RECT rect;
rect.left = 0;
rect.top = 0;
if(m_isFullscreen) { rect.right = 1280; } else { rect.right = 640; }
if(m_isFullscreen) { rect.bottom = 1024; } else { rect.bottom = 480; }
AdjustWindowRectEx(&rect, dwStyle, false, dwExStyle);

SetWindowLongPtr(m_hwnd, GWL_STYLE, dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, dwExStyle);
if(m_isFullscreen)
{
    MoveWindow(m_hwnd, 0, 0, 1280, 1024, true);
}
else
{
    MoveWindow(m_hwnd, 0, 0, 640, 480, true); // windowed
}

И это более или менее.Некоторый другой поддерживающий код и проверка ошибок, но это то, что я делаю ... dmSavedSettings сохраняется до того, как m_hwnd назначен из NULL, а не после.Мое начальное создание окна работает нормально, и полноэкранный режим работает нормально.Это просто возвращение к Windowed после того, как в полноэкранном режиме это проблема.

Ответы [ 2 ]

2 голосов
/ 29 августа 2011

Как упоминает datenwolf в комментарии другого ответа, вы хотите использовать SetWindowPos () вместо MoveWindow () при использовании SetWindowLongPtr ().

Мои проблемы с грязным фоном были решены вызовом ChangeDisplaySettings (NULL, 0) ПОСЛЕ изменения размера моего окна. Выполнение этого раньше мало что делает, но потом, кажется, работает нормально.

2 голосов
/ 27 августа 2011

Если вы установите нулевую кисть фона в своем классе окон, окна не будут очищаться автоматически.Вы должны добавить обработчик WM_PAINT, который вызывает ваш обработчик отображения OpenGL, который в свою очередь очищает область просмотра ( glClearColor ) и перерисовывает.

...