如何解决GetParent / EnumChildWindows不对称问题?

时间:2010-02-12 17:25:15

标签: c++ c user-interface winapi

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

 |
 + 002004D6 "MyRootWindow1" FooClassName
 |   |
 |   + 001F052C "MyChildWindow" ClassOfChildWindow
 |
 \ 001D0A8C "MyRootWindow2" SomeOtherClassName

有两个根窗口002004D6001D0A8c,前一个窗口有一个子窗口001F052C

现在,这一切都很好,并且发现它是否不是一件事:在子窗口上调用GetParent(或在Spy ++中观察“父窗口”或“所有者窗口”字段)({ {1}})产生001F052C

阅读:“MyChildWindow”是“MyRootWindow1”的子节点,但“MyRootWindow1”不是“MyChildWindow”的父节点。相反,“MyChildWindow”的父级是“MyRootWindow2” - 但是,要完成此操作,枚举“MyRootWindow2”的子级不会产生“MyChildWindow”。

这是一个非常静态的GUI应用程序,因此这里没有任何竞争条件。

有人知道这会怎么样吗?有谁知道如何解决这个问题?直到 现在,我使用GetParentEnumChildWindows来获取给定HWND的父(或子),我假设这种关系是对称的。可能还有其他我应该使用的东西吗?

编辑:以下是演示此问题的小型C ++程序的代码:

001D0A8C

请注意'child'对象如何设置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

2 个答案:

答案 0 :(得分:3)

嗯,这当然没有多大意义。它闻起来像儿童窗口正在重新养育自己。这是.NET Windows Forms中的常用技术,它有一个“停放窗口”,当窗口样式发生变化时,子控件可以在需要重新创建容器窗口时找到临时主页。这不是一个非常明显的效果,它也是暂时的。

另一种远程可能性是SetParent()。它具有appcompat行为以支持旧的Windows 3.x程序。它的SDK文档很好地解释了它,简而言之,一个窗口可以是父级但不设置其WS_CHILD样式标志。 Adobe Acrobat Reader是执行此操作的程序的典型示例。对我来说,EnumChildWindows会产生什么影响。

最后但并非最不重要:不要忘记Spy ++提供了窗口的静态视图。按F5更新窗口列表对于跟踪更改非常重要。

不是很好的解释。试着找出哪个顶层窗口是活动的,我怀疑它是否有效。

答案 1 :(得分:3)

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

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

你应该可以调用GetAncestor传递GA_PARENT,因为文档说: “检索父窗口。这不包括所有者,因为它与GetParent函数一样。”

请参阅Win32 window Owner vs window Parent?