Windows' Maximize Policy, or "Why do all my programs start with maximized windows?"

Introduction

Screenshot of a maximized dialog that is meant to not to be resizedYou use your new computer, everything works fine, until you use some application that starts with some small dialog. Even though the dialog should be small, it stretches over the whole desktop. There is no restore button, no taskbar, all you have is the close button and dialog controls. The following explains why this happens and what you can do about it.

Temporary fix

To get the maximized window to its correct size, double-click the window caption, which does the same as the missing restore button.

Permanent fix

So far no native approach is known, as the behaviour seems to depend on, among others, the available RAM and screen size. I wrote a small tool that can switch this behaviour on and off on supported platforms. You can either run it manually (GUI) or run it on every logon (/setstate parameter).

Why

This is a work-in-progress, aka. I got lazy while investigating this further, so parts of the text may not be completely coherent.

Short version

As of Windows 8, any application started with ShellExecuteEx (and derivates) with nShowCmd set to SW_SHOWNORMAL (1) is started with SW_SHOWMAXIMIZED (3) on certain hardware configurations. When an application starts, the first ShowWindow call ignores the nShowCmd argument and uses the value that the application was started with, irrespective of whether the first window supports that mode or not.

Long version

During the ongoing tablet-hype, Windows 8 introduced tablet mode. In that mode all applications run maximized. In an probable effort to maintain compatibility and usability, the shell starts all applications as maximized, when the device is considered to be a low-end tablet. This means, that when ShellExecuteEx (and derivates) is called, then after a lot of preparation work, right before starting the application, the code calls ApplyMaximizePolicy (windows.storage.dll) on the nShowCmd value. If it is SW_SHOWNORMAL then it consults ShouldLaunchEverythingMaximized, which in turn consults GetProp(GetShellWindow(), 0x464). If the result is TRUE, nShowCmd is updated to SW_SHOWMAXIMIZED and the application starts. Since the rule is, that the first ShowWindow call in an application ignores the nShowCmd argument and instead is shown according to the STARTUPINFO (initialized from nShowCmd), if the first window happens to be a fixed size dialog, it is maximized regardless.

The property is set in CDesktopBrowser::_UpdateShouldLaunchEverythingMaximized (shell32.dll), after checking if the system has 1 monitor (SM_CMONITORS), Windows::Internal::DeviceCapabilitiesW::IsLowMemory is true and Windows::Internal::DeviceCapabilitiesW::IsScreenSizeRequirementMet(0) is also true (SmallScreenEnhancements, IsScreenPresentMatchingSizeCondition true)

If the first window is a MessageBox dialog, it does not count towards the ShowWindow handling (it is explicitly exempted).

There is also an old, unrelated, hidden Explorer setting Software\Microsoft\Windows\CurrentVersion\Explorer\MaximizeApps, which changes SW_SHOWNORMAL, SW_SHOWDEFAULT, SW_SHOW and SW_RESTORE to SW_SHOWMAXIMIZED in calls to ShellExecuteEx (and derivates), but this is disabled by default.