The documentation for the WM_SHOWWINDOW
message
points out that the message is not sent under certain circumstances.
But what if you want to know when the window is shown,
including in the cases where you don’t get WM_SHOWWINDOW
?
The WM_WINDOWPOSCHANGED
message is sent at the end of the
window state change process.
It sort of combines the other state change notifications,
WM_MOVE
,
WM_SIZE
, and
WM_SHOWWINDOW
.
But it doesn’t suffer from the same limitations
as WM_SHOWWINDOW
,
so you can reliably use it to react to the window being shown or hidden.
The handler would go something like this:
void OnWindowPosChanged(HWND hwnd, const WINDOWPOS *pwp) { if (pwp->flags & SWP_SHOWWINDOW) { window_was_shown(); } if (pwp->flags & SWP_HIDEWINDOW) { window_was_hidden(); } if (!(pwp->flags & SWP_NOMOVE)) { window_moved_to(pwp->x, pwp->y); } if (!(pwp->flags & SWP_NOSIZE)) { window_resized_to(pwp->cx, pwp->cy); } } HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGED, OnWindowPosChanged);
Note also that if you don’t pass the WM_WINDOWPOSCHANGED
message to DefWindowProc
, then you won’t get
WM_MOVE
or WM_SIZE
messages, since it is
DefWindowProc
that converts WM_WINDOWPOSCHANGED
into the WM_MOVE
and WM_SIZE
messages.
“If WM_WINDOWPOSCHANGED
is redundant with
WM_MOVE
,
WM_SIZE
, and
WM_SHOWWINDOW
,
then why do we have those other messages anyway?”
The WM_WINDOWPOSCHANGED
message wasn’t invented until
Windows 3.1.
Prior to that, you had no choice but to react to those other messages.
You can think of those other three messages as legacy messages now.
There’s nothing wrong with them, but they’re kind of old-fashioned now.
Next time, we’ll look at the companion message
WM_WINDOWPOSCHANGING
.
Postscript:
This entry was inspired by an actual customer question
regarding the cases where WM_SHOWWINDOW
message is not sent
if the program is run with the SW_SHOWMAXIMIZED
state.
Unfortunately, one detail I missed in the customer’s question was the
remark that they need to know when the window is shown because it is
“critical for the application to initialize its state.”
I didn’t follow up on that little remark, but I should have,
because it’s very strange to do initialization work when a window
is shown.
What if the window is never shown?
Does this mean that the program will never initialize itself?
(For example, somebody might have run your program with the
SW_HIDE
state.)
The WM_NCCREATE
and WM_CREATE
are the
more traditional places to do window initialization.
0 comments