Date: | July 7, 2004 / year-entry #270 |
Tags: | code |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20040707-00/?p=38523 |
Comments: | 14 |
Summary: | If you have a minimized window and want to know where it will go when you restore it, the GetWindowPlacement function will tell you. In particular, the rcNormalPosition tells you where the window would go if it were restored (as opposed to minimized or maximized). One perhaps-non-obvious flag is WPF_RESTORETOMAXIMIZED. This flag indicates that the... |
If you have a minimized window and want to know where it will go when you restore it, the GetWindowPlacement function will tell you. In particular, the One perhaps-non-obvious flag is WPF_RESTORETOMAXIMIZED. This flag indicates that the window is currently minimized, but if the user selects "Restore", it will restore to its maximized instead of restored state. (This may seem strange, but you see it every day without even realizing. Take a window and maximize it. Now minimize it. Now click the taskbar button to re-open the window. Notice that it returns to its maximized state, not to its restored state. Imagine how frustrated you would be if it returned to its restored state instead. You'd have to keep re-maximizing the window.) The GetWindowPlacement and SetWindowPlacement functions are typically used by programs that wish to save/restore window positioning information across runs. You should also be aware that the coordinate system for window placement is not screen coordinates, but rather workspace coordinates. The consequence of getting this wrong is that your window creeps up (or to the left) over time, eventually getting itself stuck underneath the taskbar. |
Comments (14)
Comments are closed. |
Sort of related(ish) — I keep my taskbar at the top of the screen, and if an app is in a "not responding" state and is minimised then restored, it ends up under the taskbar and with a blank area at the bottom, and you can move it about.
Furthermore, if you move the app while it’s thinking then when it starts responding again it tends to get a bit confused as to where it is on the screen. Restoring then maximising usually results in it being in a fixed position somewhere off-centre…
(And anyone who has a taskbar at the top may want to look at "Y’z Shadow" — it adds a nice dropshadow effect to windows, which is its main purpose, but it will also move any apps that try and stick themselves under the taskbar.)
A question that I asked myself a long time: How does the window manager minimizes a window? As far as I can see all the the window mangager does is moving the window to the location (-32000; -32000) so it is entirely out of view. Is that right?
I love Get/SetWindowPlacement. You can pretty much just stream all of the results to make your app start just like it ended.
Is there any plans for a Get/SetWPEx to deal with multimon? It would be nice if it remembered both the layout of the window AND the original resolutions of the monitors to make intelligent decisions on how to restore the window after monitors have been moved and/or screen resolutions have been changed. I know an app can do this, but it’s something done often enough that it might be nice for Windows.
"Workspace coordinates", new word for me!
Speaking of which, I once coded a Messenger style popup window and had to FindWindow() the taskbar and then do some math to correctly position the popup.
Is there some easier way to convert between workspace and screen coordinates?
Be careful when using GWP/SWP to save and restore state. Many things can go wrong like user changed dpi, fonts, other display settings, removed a monitor, resize/moved the taskbar, etc. SWP didn’t send a WM_GETMINMAXINFO msg the last time I checked so if you’re trying to constrain it to some size(s), you’ll need to do it yourself.
I think you can convert between screen to workspace coords using the MONITORINFO struct in GetMonitorInfo. But it doesn’t work in Windows 95.
Robert> Call SHAppBarMessage() with the message ABM_GETTASKBARPOS to get the Taskbar location in screen coords.
What is the difference between minimizing an application by clicking the minimize button and by clicking its button on the taskbar?
I noticed that when I click on the taskbar the app gets WM_ACTIVATEAPP FALSE, followed immediately by WM_ACTIVATEAPP TRUE. So I end up using another application, while the first thinks that it is still active. Why is that happening? I’ve seen this on both Win 2000 and XP.
Thanks for the tips Mike and asdf! I just tried the GetMonitorInfo method and it works great.
Having an interest in .net, I checked and found the WorkingArea property of Sys.Win.Frm.Screen is the same as GetMonitorInfo.
But beware, the info in the screen object seems to get cached. Ask for WorkingArea, move the taskbar, then ask for it again. The 2nd call returns the old information. :-0
One thing I never got: why didn’t the gui return the usable workspace as the root window (excluding the taskbar)? Would this have just made things even more complicated?
Max,
I’m just guessing here, because I wasn’t doing Windows programming during the pre-95 days, but here’s what I think is going on…
In those days, when an app was minimised it would simply appear as an icon on the desktop. That icon was still the window, and the application simply noticed that it was in the minimised state and adjusted its WM_NCPAINT handler to render the 32×32 icon and caption instead. The window manager just had to set the minimised style and move and size the window to the size of an icon.
Since Win95, apps don’t minimise to icons anymore. You can see what they do if you kill off Explorer and minimise a window, or more easily load a standard MDI application and minimise one of the child windows. Instead, the window manager makes the window the minimum height possible and the NCPAINT message just paints a different caption on the "Minimise" button. All this NCPAINT stuff is handled by the built-in DefWindowProc by default, so all sane apps adopt the new behavior magically. (Some insane apps probably overrode things and needed some compatibility shims, but I’ve never seen one.)
Now this is where I really start guessing, although I suspect I’m close. While Explorer is loaded, it has to look like the application is "minimised" into the taskbar, and drawing the minimised version of the window would spoil the effect.
What Explorer does, then, is to notice that a window has been maximised and adjust the pretty whooshy animation to go to the taskbar button instead. The window still needs to go somewhere, though, so it gets shifted way offscreen where it won’t bother anyone while it’s in its minimised state.
If I’ve got this all drastically wrong, hopefully Raymond will correct me! :)
Only if you didn’t register an icon in the wndclass, you’d have to do something like:
http://groups.google.com/groups?selm=CJuI6C.Lsz%40microsoft.com
Fun times.
Joe,
Thanks a lot for your answer!
Indeed, it would be nice if Raymond could write some additional lines for clarification.
btw are there any rumors that Raymond writes a book about all that incredible usefull/interesting stuff?
"Are there any rumors that…" -> you just started it by asking about it. Rumors are like that.