Win32 Window gets stuck as the top-most window

This topic is 1515 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hiya. So in my "Engine" I'm able to switch window resolutions(800x600, 1024x768, & fullscreen), but if I switch into fullscreen then back into a windowed mode the window gets stuck at the top-most window. No matter what. If I click on a window, it displays behind my engine window. This ONLY happens after I come out of fullscreen. I Googled it and I couldn't really find anything useful. Here is my code to change the window:

bool Window::ChangeWindowMode(int windowMode)
{
if(windowMode == Window::m_WindowProperties.m_windowMode)
{
return false;
}

if(windowMode == WindowModes::WM_800X600)
{
Window::m_WindowProperties.m_windowMode = WindowModes::WM_800X600;
m_WindowProperties.m_windowWidth = 800;
m_WindowProperties.m_windowHeight = 600;
m_WindowProperties.m_windowPosX = (GetSystemMetrics(SM_CXSCREEN) - m_WindowProperties.m_windowWidth) / 2;
m_WindowProperties.m_windowPosY = (GetSystemMetrics(SM_CYSCREEN) - m_WindowProperties.m_windowHeight) / 2;

if(m_WindowProperties.m_windowMode == WindowModes::WM_FULLSCREEN)
{
ChangeDisplaySettings(nullptr, 0);
}

SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, WS_EX_OVERLAPPEDWINDOW);
SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME);
SetWindowPos(m_hWnd, nullptr, m_WindowProperties.m_windowPosX, m_WindowProperties.m_windowPosY,
m_WindowProperties.m_windowWidth, m_WindowProperties.m_windowHeight, SWP_SHOWWINDOW | SWP_NOZORDER);

}
else if(windowMode == WindowModes::WM_1024X768)
{
Window::m_WindowProperties.m_windowMode = WindowModes::WM_1024X768;
m_WindowProperties.m_windowWidth = 1024;
m_WindowProperties.m_windowHeight = 768;
m_WindowProperties.m_windowPosX = (GetSystemMetrics(SM_CXSCREEN) - m_WindowProperties.m_windowWidth) / 2;
m_WindowProperties.m_windowPosY = (GetSystemMetrics(SM_CYSCREEN) - m_WindowProperties.m_windowHeight) / 2;

if(m_WindowProperties.m_windowMode == WindowModes::WM_FULLSCREEN)
{
ChangeDisplaySettings(nullptr, CDS_GLOBAL);
}

SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, WS_EX_OVERLAPPEDWINDOW);
SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME);
SetWindowPos(m_hWnd, nullptr, m_WindowProperties.m_windowPosX, m_WindowProperties.m_windowPosY,
m_WindowProperties.m_windowWidth, m_WindowProperties.m_windowHeight, SWP_SHOWWINDOW | SWP_NOZORDER);

return true;
}
else if(windowMode == WindowModes::WM_FULLSCREEN)
{
Window::m_WindowProperties.m_windowMode = WindowModes::WM_FULLSCREEN;
m_WindowProperties.m_windowWidth = GetSystemMetrics(SM_CXSCREEN);
m_WindowProperties.m_windowHeight = GetSystemMetrics(SM_CYSCREEN);
m_WindowProperties.m_windowPosX = m_WindowProperties.m_windowPosY = 0;

DEVMODE dmScreenSettings;

ZeroMemory(&dmScreenSettings, sizeof(DEVMODE));
dmScreenSettings.dmPelsWidth = m_WindowProperties.m_windowWidth;
dmScreenSettings.dmPelsHeight = m_WindowProperties.m_windowHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmDisplayFlags = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;

ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);

SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_POPUP);
SetWindowPos(m_hWnd, nullptr, m_WindowProperties.m_windowPosX, m_WindowProperties.m_windowPosY,
m_WindowProperties.m_windowWidth, m_WindowProperties.m_windowHeight, SWP_SHOWWINDOW | SWP_NOZORDER);
}

return true;
}

void DeviceResources::ChangeWindowMode(int windowMode)
{
if(m_Window.ChangeWindowMode(windowMode))
{
m_d3dpp.BackBufferWidth = m_Window.m_WindowProperties.m_windowWidth;
m_d3dpp.BackBufferHeight = m_Window.m_WindowProperties.m_windowHeight;

if(windowMode == WindowModes::WM_FULLSCREEN)
{
m_d3dpp.Windowed = false;
}
else
{
m_d3dpp.Windowed = true;
}

m_pDevice->Reset(&m_d3dpp);
}
}


Share on other sites

Yeah, I noticed that. DX (at least with 9) adds the WS_EX_TOPMOST style to your window. So whenever I return from fullscreen I remove the style again. Before going fullscreen I store the current window styles (both style and extended style), and restore them afterwards.

Use SetWindowLong with GWL_EXSTYLE to do that.

Share on other sites

Yeah, I noticed that. DX (at least with 9) adds the WS_EX_TOPMOST style to your window. So whenever I return from fullscreen I remove the style again. Before going fullscreen I store the current window styles (both style and extended style), and restore them afterwards.

Use SetWindowLong with GWL_EXSTYLE to do that.

I did use SetWindowLong, it still remains in the foreground.

Share on other sites

Try adding ChangeDisplaySettings( NULL, NULL ) when coming out of fullscreen mode.

Alternatively, forget about using ChangeDisplaySettings entirely, and just use the native desktop resolution. You can then render to a smaller offscreen buffer and then scale up to the screen size.

Share on other sites
I got it to work properly. I added HWND_NOTTOPMOST to the second parameter of SetWindowPos. Thank you for the help.

Share on other sites

    if(windowMode == WindowModes::WM_800X600)
{
Window::m_WindowProperties.m_windowMode = WindowModes::WM_800X600;
...
if(m_WindowProperties.m_windowMode == WindowModes::WM_FULLSCREEN)// never gets executed?? m_windowMode is already set to WM_800X600

Also, after ZeroMemory(&dmScreenSettings, sizeof(DEVMODE));, you need to set dmScreenSettings::dmSize to sizeof(DEVMODE). See the docs. With dmSize cleared to zero, it's likely the ChangeSettings is ignored, and possibly returns an error. As you don't check for any errors in your code, that may have been a problem. Just a suggestion, but when something doesn't work as expected, checking for errors is the first thing to do.

EDIT: Actually, checking for errors is something you should do anyway. Most (all?) API calls provide some sort of indication of success or failure. Check for them, and handle them appropriately. Saves time in the long run.

Edited by Buckeye

Share on other sites

"I got it to work properly. I added HWND_NOTTOPMOST to the second parameter of SetWindowPos. Thank you for the help."

Nevertheless, you should still call ChangeDisplaySettings( NULL, NULL ) when coming out of fullscreen mode to undo the temporary mode change.

Edited by mark ds

Share on other sites

"I got it to work properly. I added HWND_NOTTOPMOST to the second parameter of SetWindowPos. Thank you for the help."

Nevertheless, you should still call ChangeDisplaySettings( NULL, NULL ) when coming out of fullscreen mode to undo the temporary mode change.

I do.

Share on other sites

..call ChangeDisplaySettings.. I do.

See my comments above. Have you determined that: 1. the code is reached? 2. there is no error?

Share on other sites

..call ChangeDisplaySettings.. I do.

See my comments above. Have you determined that: 1. the code is reached? 2. there is no error?
Yes. I fixed that. Thank you for pointing that out. Silly mistake on my part.

1. 1
Rutin
34
2. 2
3. 3
4. 4
5. 5

• 12
• 14
• 9
• 9
• 9
• Forum Statistics

• Total Topics
633337
• Total Posts
3011415
• Who's Online (See full list)

There are no registered users currently online

×