c++ - 我如何解决 GetParent/EnumChildWindows 不对称问题?

标签 c++ c user-interface winapi

我最近用 Microsoft 的 Spy++ 检查了一个 GUI,发现了一个奇怪的结构;它看起来像这样(警告,前面的 ASCII 艺术):

 |
 + 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 );

请注意“子”对象如何设置了 WS_POPUP WS_OVERLAPPED,但没有设置 WS_CHILD

最佳答案

GetParent 的文档说明: “请注意,尽管它的名称如此,但此函数可以返回所有者窗口而不是父窗口。”

由于您没有创建子窗口,我猜您遇到了这种情况。

您应该能够调用 GetAncestor 并传递 GA_PARENT,如文档所述: “检索父窗口。这不包括所有者,因为它使用 GetParent 函数。”

参见 Win32 window Owner vs window Parent?

关于c++ - 我如何解决 GetParent/EnumChildWindows 不对称问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2253725/

相关文章:

java - 我可以计算计算机中的图像被查看了多少次并将计数数存储在java文件或cpp文件中?

c - '.' or ' ->'C 结构体访问器

multithreading - 继续 OS X - 两个库调用系统函数

c++ - 合并排序数组 - 高效的解决方案

c++ - 在没有项目的情况下使用Dev c++在窗口中绘制文本

c++ - 用互联网浏览器的客户区填充窗口的客户区

python - 在 BeagleBone Black 中创建和链接 GUI

.net - 创建 .NET 组件,例如 Windows 搜索工具栏

c++ - 如何从父模板函数访问子成员?

c++ - 这种原子指针交换模式安全吗?