I think I found a bug in GetWindowPlacement()

Alex Sokolek

Member
Joined
Apr 5, 2024
Hi. I think I found a bug in GetWindow{Placement().​
I save and restore the window placement using the registry as an intermidiary.​
For save...​
```​
(In WndProc)
case WM_DESTROY:
{
WINDOWPLACEMENT wp;
ZeroMemory(&wp, sizeof(wp));
wp.length = sizeof(wp);
GetWindowPlacement(hWnd, &wp);
pAppReg->SaveMemoryBlock(_T("WindowPlacement"), (LPBYTE)&wp, sizeof(wp));
}
```

And for restore...

```
(In InitInstance)
WINDOWPLACEMENT wp;
if (pAppReg->LoadMemoryBlock(_T("WindowPlacement"), (LPBYTE)&wp, sizeof(wp)))
{
if (wp.flags == 0 && wp.showCmd == SW_MINIMIZE) wp.flags = WPF_SETMINPOSITION; // This is the bug fix
SetWindowPlacement(hWnd, &wp);
}
```

pAppReg is a pointer to a class that saves and restores memory blocks to and from the registry. See the line that says // This is the bug fix. If I omit the line and the window was minimized, it becomes hidden when I do the restore. My question: Is this a bug? Thank you.
 
Hello,

What you've encountered might seem like a bug, but it is actually a feature behaving as expected in line with the documentation of the GetWindowPlacement() and SetWindowPlacement() functions. You're betting on flags == 0 when a window is in minimized state, but actually, when the window is minimized manually, it doesn't automatically set WPF_SETMINPOSITION flag.

The WPF_SETMINPOSITION flag (as per MSDN documents) is defined as "The coordinates of the minimized window may be specified. This flag must be specified if the coordinates are set in the ptMinPosition member." This means if you setup ptMinPosition and you want it to be used, you must define this flag.

The reason for your program behaving as it is, is because of how "ptMinPosition" interacts with "flags" and "showCmd". When a window is manually minimized, Windows assigns a minimized position off-screen. If a WINDOWPLACEMENT with WPF_SETMINPOSITION not set is passed to SetWindowPlacement where showCmd == SW_MINIMIZE, it uses the position that was manually set - which is evidently off-screen in your case.

Your fix is absolutely correct - it ensures that when you restore a window that was minimized, that ptMinPosition be respected as per your initialization of the WINDOWPLACEMENT structure. It is certainly an unexpected behaviour which could be easily interpreted as a bug, but it's more like a gotcha in the API's behavior.

Ergo, it isn't a bug in GetWindowPlacement(), but rather, the unusual/complex behaviour of SetWindowPlacement() due to the interaction between flags, showCmd and 'ptMinPosition'.

Hope this gives you a better understanding.
 
p.s. I tried the trick you told me about bracketing code with triple back ticks. It did not work. Did I do something wrong?
 
Back
Top Bottom