• Advertisement
Sign in to follow this  

Win32 Window gets stuck as the top-most window

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
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.

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites

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.

Edited by Buckeye

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement