Holy cow, I wrote a book!
MontagFTB noticed that some controls have the problem that
if you reparent the control, it still sends notifications to its
We looked at the faulty diagnosis last time.
What's the real reason?
The control cached its original parent window.
Most complex controls communicate with the parent window frequently,
and in order to avoid calling GetParent,
the control gets its parent once and caches the value for future use.
Under normal conditions, this cache works very well
since reparenting a window is extremely rare and is generally
considered an unusual condition.
Like the adoption of a child,
it's the sort of thing you should only be doing with the coordination
of all three parties (the old parent, the new parent, and the child).
When you reparent the control,
the cached value in the child window is no longer correct.
But since you didn't coordinate this with the child window,
the control doesn't know this, and it keeps talking to the old parent.
Unlike the Post Office, you can't submit a change of address form
to the window manager and tell it,
if somebody tries to send a message to windows X,
deliver it to window Y if the return address is window Z."
(Actually, the Post Office stops forwarding mail after one year.)
Since window reparenting is considered to be an unusual condition,
most controls don't have provisions for telling them,
"Hey, I reparented you. Please send future notifications to that
window over there."
The window manager is fine with all your reparenting games,
but the other participants may have made assumptions based on
the stability of the window hierarchy.
Where does that leave MontagFTB?
(It is at this point where a general topic gradually turns into
addressing questions that are applicable only to MontagFTB's
situation and aren't all that useful to others.
This is something I try to avoid, because this is a blog,
not a consulting service.)
First, you can avoid the staging window and just create the controls
with the correct parent.
I don't know why the staging window was necessary,
so this may not be a viable solution.
If it was merely to avoid flicker, then you can create the controls
as hidden windows, and then do a massive ShowWindow
when they are ready.
Or you can create the controls at negative coordinates (so they
don't appear inside the parent's client rectangle),
and then when you're ready,
perform a big EndDeferWindowPos
to move them all into position at once.
If you really need to have the staging window,
you can have the staging window do the message forwarding.
If it receives a WM_COMMAND or
WM_NOTIFY notification message from one of these
given-away child windows,
it just forwards the message to the new owner.
However, this violates the guideline that
"When reparenting a window, the old parent, the new parent, and the child
all need to be involved in the process if you want the adoption to
so I would not recommend it.
If you don't want to make the staging window have to deal
with message forwarding (for example,
if you intend on destroying the staging window once you have removed
all the child windows),
then you can insert a level of redirection:
Create a container window as a child of the staging window,
and create the child windows as children of the container.
Then when it's time to reparent the controls,
move the container window to the new parent.
This adheres to the guideline because the windows involved in the
(the final destination, the staging window, and the container window)
are all under your control,
and therefore you can make sure all internal state is correct when
you change the bookkeeping relationship among them.
And since the controls are destined for a dialog box,
you should give the container the WS_EX_CONTROLPARENT
style so that they can participate in dialog box navigation.