Итак, у меня запущено приложение 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, а не после этого. Мое первоначальное создание окна работает нормально, и полноэкранный режим работает нормально. Он просто возвращается в оконный режим после полноэкранного режима, вот в чем проблема.
2 ответа
Как упоминает datenwolf в другом комментарии к ответу, вы хотите использовать SetWindowPos () вместо MoveWindow () при использовании SetWindowLongPtr ().
Мои грязные проблемы с фоном были решены вызовом ChangeDisplaySettings (NULL, 0) ПОСЛЕ изменения размера моего окна. Выполнение этого раньше мало что дает, но потом, похоже, работает нормально.
Если вы установите нулевую фоновую кисть в своем классе окна, окна не будут очищаться автоматически. Вы должны добавить обработчик WM_PAINT, который вызывает ваш обработчик отображения OpenGL, который, в свою очередь, очищает область просмотра ( glClearColor ) и перерисовывает.
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .