Win32 Window gets stuck as the top-most window

Started by
8 comments, last by Renthalkx97 9 years, 7 months ago

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);
	}
}
Advertisement

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.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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.

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.

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

Thanks for posting your solution.

Other comments (perhaps immaterial now):


    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.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

"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 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.


..call ChangeDisplaySettings.. I do.

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

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

..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.

This topic is closed to new replies.

Advertisement