0
votes

So i'm trying to write a toggle fullscreen function for my game.

It works.. kinda, problem is the first SetWindowLongPtr() call causes a WM_SIZE message to be queued and sent to my WNDPROC (on MSDN i read changes to the window style are only cached and have to be applied using SetWindowPos() though).

SetWindowLongPtr(m_hWnd, GWL_STYLE, dwStyle);
SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, dwExStyle);
SetWindowPos(m_hWnd, NULL, fullscreen ? 0 : window.left, fullscreen ? 0 : window.top, window.right, window.bottom, SWP_NOZORDER | SWP_FRAMECHANGED);
ShowWindow(m_hWnd, SW_SHOW);

When changing from windowed to fullscreen mode the client area gets resized to the window rect and updated like that (so now 'contains' the bars etc.). Apart from causing my program to destroy the Vulkan context twice, this makes me save the wrong window dimensions for reverting to windowed mode later on (this is done when WM_SIZE occurs and when the game is in fullscreen mode).

Afterwards it's sized to the correct dimensions by SetWindowPos().

I mean i could certainly just hack in a bool to discard the WM_SIZE message when it should be, but i'm looking for a better and maybe less bodged way. Is there a function to temporarily disable window messages or just the user def WNDPROC?

1
need not disable windows messages but correct handle itRbMm
I just do this and it works: SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)DefWindowProc); SetWindowLongPtr(m_hWnd, GWL_STYLE, dwStyle); SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, dwExStyle); SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)StdWndProc);AxMedia
This should not be a problem of course. Crystal ball says that you simply forget to also store the window state. Required since that tells you how you need to recreate the window when you start back up, assuming you want to resume again in full-screen mode.Hans Passant

1 Answers

0
votes

This is the function that I use to toggle fullscreen on and off. I got this function from Raymond Chen. I don't know if it messes with Vulkan though but it works with OpenGL.

WINDOWPLACEMENT GlobalWindowPosition = {sizeof(GlobalWindowPosition)};
void ToggleFullscreen(HWND WindowHandle)
{
    DWORD Style = GetWindowLong(WindowHandle, GWL_STYLE);
    if(Style & WS_OVERLAPPEDWINDOW)
    {
        MONITORINFO MonitorInfo = {sizeof(MonitorInfo)};
        if(GetWindowPlacement(WindowHandle, &GlobalWindowPosition) &&
           GetMonitorInfo(MonitorFromWindow(WindowHandle, MONITOR_DEFAULTTOPRIMARY),
                          &MonitorInfo))
        {
            SetWindowLong(WindowHandle, GWL_STYLE,
                          Style & ~WS_OVERLAPPEDWINDOW);
            SetWindowPos(WindowHandle, HWND_TOP,
                         MonitorInfo.rcMonitor.left, MonitorInfo.rcMonitor.top,
                         MonitorInfo.rcMonitor.right - MonitorInfo.rcMonitor.left,
                         MonitorInfo.rcMonitor.bottom - MonitorInfo.rcMonitor.top,
                         SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
        }
    }
    else
    {
        SetWindowLong(WindowHandle, GWL_STYLE, Style | WS_OVERLAPPEDWINDOW);
        SetWindowPlacement(WindowHandle, &GlobalWindowPosition);
        SetWindowPos(WindowHandle, NULL, 0, 0, 0, 0,
                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
                     SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
    }
}