Currently, I'm trying to make a simple Win32 application that switches back and forth between fullscreen and windowed mode. I'm using the Chromium way of doing this as a reference. I created a class to handle windows to make things simpler.
I expected this to work by toggling fullscreen when the F4 key was pressed. Unfortunately, the styles appear to be applied correctly, but the window doesn't resize or move to the correct area. It also snaps to the top left corner of the screen for a moment before it returns to its original position. For some reason, input for the window passes to the one below it when I toggle fullscreen. Then I have to go to Task Manager to kill the program because I can't close the window or application.
I've tried storing the styles of the HWND in a class variable at creation (it starts out in windowed mode) and using the value to create the necessary style for the fullscreen window and restoring the windowed mode window. I have also tried immediately getting the window styles with GetWindowLongPtr
when the ToggleFullscreen
function is called. Both of these do not work.
Here is my code:
WindowHandler.h
#include <Windows.h> // Win32 API
#ifndef WINDOWHANDLER
#define WINDOWHANDLER
class WindowHandler // WindowHandler
{
public:
WindowHandler(); // Constructor
void Destroy() { DestroyWindow(hwnd); } // Destroy the handler
void ToggleFullscreen(); // Toggle fullscreen
protected:
static LRESULT CALLBACK WindowProc // Window procedure
(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam
);
HWND hwnd; // The window
// Everything involved in fullscreen
bool fullscreen = false; // Whether the window is fullscreen or not
RECT windowRect = {}; // The restored window size
long int windowStyles = 0; // The restored window styles
long int extendedWindowStyles = 0; // The restored window extended styles
};
#endif
WindowHandler.cpp
#include "WindowHandler.h" // Header file
WindowHandler::WindowHandler() // Constructor
{
WNDCLASS wndClass = {}; // The window information
wndClass.lpfnWndProc = WindowProc;
wndClass.hInstance = GetModuleHandle(nullptr);
wndClass.lpszClassName = L"FullscreenTest";
RegisterClass(&wndClass); // Register the window
hwnd = CreateWindowEx // Create the window and store a pointer to the handler for the procedure to use
(
0,
L"FullscreenTest",
L"Stack Overflow Repro",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
nullptr,
nullptr,
GetModuleHandle(nullptr),
this
);
if (hwnd == nullptr) Destroy(); // Destroy the handler if the window is invalid
else // Otherwise...
{
GetWindowRect(hwnd, &windowRect); // Store the window size
windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE); // Store the window styles
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE); // Store the extended window styles
ShowWindow(hwnd, SW_SHOW); // Show the window
}
}
void WindowHandler::ToggleFullscreen() // Toggle fullscreen
{
if (!fullscreen) // If fullscreen is not enabled
{
MONITORINFO monitorInfo; // Get the monitor info
monitorInfo.cbSize = sizeof(monitorInfo);
GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &monitorInfo);
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyles & ~(WS_CAPTION | WS_THICKFRAME)); // Set the window styles
SetWindowLongPtr // Set the extended window styles
(
hwnd,
GWL_EXSTYLE,
extendedWindowStyles & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)
);
SetWindowPos // Resize, move, and refresh the window
(
hwnd,
nullptr,
monitorInfo.rcMonitor.left,
monitorInfo.rcMonitor.top,
monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED
);
fullscreen = true; // Indicate that fullscreen is on
}
else // Otherwise...
{
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyles); // Set the window styles
SetWindowLongPtr(hwnd, GWL_EXSTYLE, extendedWindowStyles); // Set the extended window styles
SetWindowPos // Resize, move, and refresh the window
(
hwnd,
nullptr,
windowRect.left,
windowRect.top,
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top,
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED
);
fullscreen = false; // Indicate that fullscreen is off
}
}
LRESULT CALLBACK WindowHandler::WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) // Window procedure
{
WindowHandler* handlerPtr; // Pointer to the window handler
if (message == WM_CREATE) // If the window is being created...
{
CREATESTRUCT* createStruct = reinterpret_cast<CREATESTRUCT*>(lParam); // Get the pointer's container
handlerPtr = reinterpret_cast<WindowHandler*>(createStruct->lpCreateParams); // Get the pointer
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)handlerPtr); // Store the pointer
}
else handlerPtr = reinterpret_cast<WindowHandler*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); // Otherwise, get the pointer
if (handlerPtr) { // If the pointer is valid...
switch (message)
{
case WM_PAINT: // Paint the window
{
PAINTSTRUCT paintStruct;
HDC hdc = BeginPaint(hwnd, &paintStruct);
FillRect(hdc, &paintStruct.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));
EndPaint(hwnd, &paintStruct);
}
return 0;
case WM_DESTROY: // Destroy the window
PostQuitMessage(0);
return 0;
case WM_KEYDOWN: // Process input
switch ((int)wParam)
{
case VK_ESCAPE: // Quit if the escape key is pressed
handlerPtr->Destroy();
break;
case VK_F4: // Toggle fullscreen if F4 is pressed
handlerPtr->ToggleFullscreen();
break;
}
return 0;
default: // Do the default action if the message was not processed
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
else return DefWindowProc(hwnd, message, wParam, lParam); // Do the default action if the pointer is not valid
}
main.cpp
#include "WindowHandler.h" // Window handler
int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) // Win32 main function
{
WindowHandler repro; // Create a window handler
MSG msg = {}; // Message structure
while (GetMessage(&msg, nullptr, 0, 0)) // Message loop
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
Exclusive Fullscreen Mode is a new feature available for the macOS Luna Secondary App 5.1 or newer and allows you to disable multi-tasking gestures and keyboard commands like command+tab, app switching with gestures, and more when using your secondary screen's keyboard and mouse/trackpad.
Open the program, maximize the window by clicking the square icon in the upper-right corner. Then, press and hold the Ctrl key and close the program. Re-open the program to see if it opens as maximized.
Using the F11 key on your computer's keyboard will let you both enter and exit full-screen mode in many applications. If you use a laptop, you might need to press Fn + F11 to activate this keyboard shortcut.
Replace:
windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE);
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
ShowWindow(hwnd, SW_SHOW); // Show the window
With:
ShowWindow(hwnd, SW_SHOW); // Show the window
windowStyles = GetWindowLongPtr(hwnd, GWL_STYLE);
extendedWindowStyles = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
The WS_VISIBLE style bit does not get set until after that first ShowWindow(SW_SHOW)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With