I recently inspect a GUI with Microsoft's Spy++ and noticed a strange structure; it looked like this (warning, ASCII art ahead):
| + 002004D6 "MyRootWindow1" FooClassName | | | + 001F052C "MyChildWindow" ClassOfChildWindow | \ 001D0A8C "MyRootWindow2" SomeOtherClassName
There are two root windows, 002004D6
and 001D0A8c
, the former one of which has one child window, 001F052C
.
Now, this would be all good and find if it wasn't for one thing: calling GetParent (or watching the 'Parent Window' or 'Owner Window' fields in Spy++) on the child window (001F052C
) yields 001D0A8C
.
Read: "MyChildWindow" is a child of "MyRootWindow1", but "MyRootWindow1" is not the parent of "MyChildWindow". Instead, the parent of "MyChildWindow" is "MyRootWindow2" - but, to make this complete, enumerating the children of "MyRootWindow2" does not yield "MyChildWindow".
This is a perfectly static GUI applications, so there are no race conditions here or anything.
Does anybody know how this can happen? Does anybody know how I can work around this? Until now, I used GetParent and EnumChildWindows to get the parent (or children) for a given HWND, and I assumed that this relationship is symmetrical. Is there maybe something else I should be using?
EDIT: Here's the code for a small C++ program which demonstrates the problem:
const HINSTANCE thisModule = ::GetModuleHandle( NULL );
HWND oldParent = ::CreateWindow( TEXT("STATIC"),
TEXT("Old parent"),
WS_VISIBLE | WS_BORDER,
0, 0, 850, 500,
NULL,
NULL,
thisModule,
NULL );
HWND child = ::CreateWindow( TEXT("STATIC"),
TEXT("This is a sample dialog"),
WS_OVERLAPPED | WS_POPUP | WS_VISIBLE | WS_BORDER,
100, 100, 300, 300,
oldParent,
NULL,
thisModule,
NULL );
HWND newParent = ::CreateWindow( TEXT("STATIC"),
TEXT("Fake main window"),
WS_VISIBLE | WS_BORDER,
0, 0, 850, 500,
NULL,
NULL,
thisModule,
NULL );
::SetParent( child, newParent );
Note how the 'child' object has WS_POPUP
and WS_OVERLAPPED
set, but not WS_CHILD
.