Why doesn’t the MoveWindow function generate the WM_GETMINMAXINFO message?


Commenter Phil Quirk asks why calling MoveWindow does not result in a WM_GETMINMAXINFO message being sent to validate the moved window size.

Well, because you moved it after all. You're being trusted to respect your own rules. After all, if you didn't want the window to be wider than 200 pixels, you shouldn't have passed nWidth=300, right?

The WM_GETMINMAXINFO message is for obtaining minimum and maximum sizing information when the sizes were chosen by a means outside the application's control, such as when you said "I'll let you choose the window size (CW_USEDEFAULT)" or when the user grabbed the corner of the window and started dragging it around. But if you yourself changed the window size, then the window manager assumes that you know what you're doing.

If you don't trust yourself to follow your own rules, you can intercept the attempt to change the window size by handling the WM_WINDOWPOSCHANGING message.

Comments (16)
  1. Neil says:

    I was always confused by the fact that MoveWindow also resized the window…

  2. Tom says:

    Even though I’ve been doing windows programming for a few years now, I’m still amazed at the intricacies of Windows Messages. I’ve always wanted some sort of diagram that shows the order that Windows Messages are delivered to a message pump in response to various conditions, operations and messages, just so I can get it all straight in my head; but I’ve never found one. Has anyone else found anything like that in a book or on the web?

    [There is no such document because the order of windows messages is (for the most part) unspecified. The order can (and does) change depending on conditions. Message order dependencies are one of the bigger categories of application compatibility issues. -Raymond]
  3. Tom says:

    @Raymond:  I don’t remember reading that chapter in your book. :)

    While application compatibility makes documenting message order difficult, it should be possible to give a relative message order as opposed to an absolute order.  For example, WM_WINDOWPOSCHANGING obviously occurs before WM_WINDOWPOSCHANGED, but that should not imply that no other messages intervene.  

    I suppose that, given the inclination and the time, it would be possible to reconstruct relative message ordering from the MSDN documentation, but I was hoping that someone had already made the effort.  After all, a good programmer is a lazy programmer.  At least, according to Larry Wall, that is. ;)

  4. John says:

    Unfortunately, nobody can be told what the message order is.  You have to reverse engineer it for yourself.

  5. asf says:

    Why do we even need MoveWindow, SetWindowPos is so much better

    [Duplicate of question already in the suggestion box. -Raymond]
  6. steveg says:

    There’s a plethora of ways to shuffle windows around the screen: MoveWindow, SetWindowPos, SetWindowPlacement, BeginDeferWindowPos, DeferWindowPos, EndDeferWindowPos, TileWindows, UpdateLayeredWindow (and probably others).

    I think it’s quirky fun choosing which one to use — "Window, how shall I move thee today?".

    They give the Win API its unique character.

  7. hexatron says:

    MoveWindow has always been special to me. One of the first things I wrote in windows (1991?) was something like

    case WM_MOVE:

    GetClientRect(hwnd, &rect);

    MoveWindow(hwnd, LOWORD(lParam), HIWORD(lParam), rect.right, rect.bottom, TRUE);

    break;

    (you don’t really need the break;–it breaks all by itself)

    So now I always use SetWindowPos :)

  8. Nicolas B says:

    There’s something that strikes me in today’s post : as a user, I like the system to prevent me from making mistakes.

    And as a developer, I certainly don’t trust myself! I *do* want the system to help me follow my own rules…

    Frankly, this goes against good coding guidelines…

    [Until you have a window that you want to restrict the size of, *unless* it’s your code which turns it into an appbar and docks it against the edge of the screen, and then you’d be asking for a way to specify the interactive resize limit separately from the programmatic resize limit. (Plus of course the performance penalty of sending an extra WM_GETMINMAXINFO message each time any window resizes, especially since the window already gets a WM_WINDOWPOSCHANGING message with the same information.) -Raymond]
  9. Pavel Minaev says:

    > Until you have a window that you want to restrict the size of, *unless* it’s your code which turns it into an appbar and docks it against the edge of the screen, and then you’d be asking for a way to specify the interactive resize limit separately from the programmatic resize limit.

    Which could, of course, be handled by a special MW_IGNORE_GETMINMAXINFO flag that should be explicitly specified where such behavior is desirable. At least that’s what I think Nicolas was getting to, and I can agree with him there that it’s better to make such things explicit in the API.

    [It’s always easy to design interfaces from the 1980’s with the philosophy of the 2000’s. Back in the 1980’s the design philosophy was “Trust the programmer. Any code that tries to second-guess the programmer slows down the system (you have a 4.77MHz processor), consumes memory (and you have only 320KB), and annoys the programmer.” -Raymond]
  10. Mook says:

    Why does an already-maximized window not get a WM_GETMINMAXINFO while the taskbar autohiding-ness is turned on (and therefore the maximized window just magically resized a bit bigger, if it used to be the whole work area)?

    ("It’s a bug", "somebody felt like it", and "here’s a bunny with a pancake on its head" are all acceptable answers.)

  11. Koro says:

    "[…] the order of windows messages is (for the most part) unspecified"

    Well I’d assume WM_NCCREATE would be the *absolute first* message a window would receive, and WM_NCDESTROY the *absolute last*, at least?

    It comes in handy when coding stuff like generic wndprocs that will just forward to a class.

  12. Rick C says:

    @Koro:  Well, you could certainly write a little program to test out that theory.

  13. Alexandre Grigoriev says:

    Koro,

    I’m afraid you missed "for the most part" part.

  14. chrismcb says:

    @Koro:

    Why would you assume that?

    You can assume that WM_NCCREATE is sent prior to the WM_CREATE, and the WM_NCDESTROY follows a WM_DESTROY. But I think you can potentially get yourself in trouble if you assume they are the first and last messages.

  15. Alexandre Grigoriev says:

    Raymond:

    "Back in the 1980’s the design philosophy was "Trust the programmer. Any code that tries to second-guess the programmer slows down the system (you have a 4.77MHz processor), consumes memory (and you have only 320KB), and annoys the programmer."

    Now, thankfully, you have craploads of memory with badass processors. Windows doesn’t trust the user. It is trying to second-guess the user and to annoy him. Hit him with "You have unused icons. Do you want to clean them" *twice* in a row (why not four times, in case he missed it not one, but three times). Or Outlook Express nagging "I will compact the messages. OK?" every time, and if the poor user agrees, OE will run *extremely poorly* designed piece of code that uses SHCopyFile instead of RenameFile, spews copy progress windows, and annoys the hell out of me.

  16. Yuhong Bao says:

    "I was always confused by the fact that MoveWindow also resized the window…"

    And the fact that CloseWindow minimizes instead of closes a window, and the fact that OpenIcon restores a window.

Comments are closed.

Skip to main content