How to stop Explorer starting my application maximized?
Asked Answered
S

2

4

Explorer seems to always start my application with SW_MAXIMIZE (STARTF_USESHOWWINDOW is set in STARTUPINFO.dwFlags). I know that ShowWindow will use this value the first time you/Windows needs to display a window but it has the unfortunate consequence of maximizing a window that should never be maximized.

My window is created with CreateDialogIndirectParam and has the following styles: WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_CLIPCHILDREN|DS_MODALFRAME|DS_CENTER|WS_VISIBLE. Why does ShowWindow not check if WS_MAXIMIZEBOX is set before allowing STARTF_USESHOWWINDOW to force SW_MAXIMIZE? Is this a bug in Windows?

This happens on a HP Stream 7 with Windows 8.1. I'm not sure if Explorer does this because it is touch enabled or because of the small screen.

Is this Explorer behavior documented anywhere and is there a way to turn it off? What is the best way to stop Explorer (or any other parent process) from affecting my initial window mode? (I don't want to block people starting me with SW_*MINIMIZE*)

WinVer.exe in system32 has the same problem: enter image description here

Streetwalker answered 8/3, 2015 at 19:0 Comment(8)
Are you sure you are clicking on the actual .exe directly, and not on a shortcut that has a "Run: maximized" setting applied to it?Lethe
@RemyLebeau Yes I'm double-clicking the .exe directly. Even if it was a shortcut my main question would still apply, how do I prevent the first call to ShowWindow from maximizing a window that does not have WS_MAXIMIZEBOX set?Streetwalker
cmd.exe /c start /MAX c:\myapp.exe also has the same issue...Streetwalker
The documentation for ShowWindow says: "the nCmdShow value is ignored in the first call to ShowWindow [...]" To me this sounds like calling ShowWindow twice in a row would produce the result you are looking for.Pung
@Pung I'm not even calling it once, I'm guessing something inside CreateWindowEx is doing it. You cannot just call it twice with SW_RESTORE but have to detect the wrong state like I do in my answer but doing this should not be necessary in the first place which is why I'm asking if people know a better way...Streetwalker
It's because you have a small screen and only 1GB of memory. Windows launches all apps maximized in this configuration.Vesicate
@RaymondChen Is this feature documented anywhere? Is there a way to turn it off? And who thought it was a good idea to maximize apps that the user cannot maximize again after the window has been restored? It also makes apps look stupid because they never expect this to happen...Streetwalker
The intent was to maximize only apps that could be maximized, but there is a bug in ShowWindow where it will also maximize non-maximizable windows if the startup info says SW_MAXIMIZE. Sorry. You can work around this by detecting that somebody is trying to launch your app maximized (GetStartupInfo) and creating a dummy window first (that will eat the bogus Maximize.)Vesicate
S
2

My first thought was to turn off STARTF_USESHOWWINDOW in the PEB if the parent wanted me to start maximized but that is too nasty and undocumented so I have not tried that yet.


Preventing any kind of size change (which is OK for my application since it is just a "modal" dialog) sort of works:

case WM_WINDOWPOSCHANGING:
  ((WINDOWPOS*)lp)->flags |= SWP_NOSIZE;
  return true;

The problem is that the window position is still set to 0 x 0 like a maximized window.


A better solution seems to be to detect and correct the problem after WM_INITDIALOG:

case WM_INITDIALOG:
  PostMessage(hDlg, WM_APP, 0, 0);
  break;
case WM_APP:
  if (IsZoomed(hDlg)) ShowWindow(hDlg, SW_SHOWNOACTIVATE);
  break;
Streetwalker answered 8/3, 2015 at 19:21 Comment(1)
Modifying the PEB does not seem to work, maybe the kernel side has its own STARTUPINFO copy...Streetwalker
W
1

I am the proud owner of several HP Stream 7 tablets and I would like to add my 2 cents here. Microsoft has made an arbitrary decision that devices with screen sizes smaller than 8 inches will behave differently than the norm. A lot of users are somewhat aware of this, but unaware that this is where your problem originates.

Windows determines a screen's size by reading the EDID information from the screen, which contains sizing information in it, in centimeters.

If no sizing information is present in the EDID, or the sizing information is below Microsoft's arbitrarily chosen 8 inch threshold, you get this apparent misbehavior which is at the very least, aggrivating to those who notice it and don't want it.

The solution is to override the default driver for the monitor in Device Manager with one that informs Windows that the screen is in fact, 8 inches or larger.

To do so, you need to first read the EDID information from the registry with a tool such as Deltacast's E-EDID Editor (free, last time I checked), and modify the size values and save the modified file someplace you can find it.

After you have modified your EDID file and saved it, download Monitor Asset Manager from EnTech (also free) and use it to create an INF file.

Once the INF file has been created, you need to restart Windows with the Advanced settings menu and choose to Disable Driver Signing Enforcement, since the INF file you created won't be digitally signed. Once disabled, open Device Manager in Windows and update the driver for the monitor using the INF file you created. You will need to confirm that you do in fact want to install the unsigned driver file.

Reboot and Windows will now behave normally with the one catch that, the onscreen keyboard will now appear a different size and will have more options available.

Sadly, Microsoft can change this behavior in the future, so there is no guarantee that through the same flawed decision making process they used to implement this in the first place, they won't force it down our throats again, using a much more difficult to counteract method.

Wert answered 5/1, 2016 at 5:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.