为什么顶级窗口的GetParent(hwnd)和(HWND):: GetWindow(hwnd,GW_OWNER)给出不同的结果?

时间:2018-11-25 19:55:14

标签: windows winapi win32gui

我一直在研究Window层次结构的工作原理,发现不一致之处。尽管大多数情况下,由两个函数调用GetParent(hwnd)(HWND)::GetWindow(hwnd, GW_OWNER)返回的值并非总是用于顶级窗口

我之所以认为这些是顶级窗口,是因为它们是使用EnumWindows()函数找到的,它们仅用于枚举顶级窗口。还使用What's the best way do determine if an HWND represents a top-level window?的答案中指定的测试hWnd==GetAncestor(hWnd,GA_ROOT)对此进行了确认。

我在#32770的窗口类AVGUI.exeComboLBoxexplorer.exenotepad++.exe,{ {1}},TeamViewer.exe,...,列表继续进行。

PrivacyIconClient.exe将返回devenv.exe中的GetParent(hwnd),但是HWND将返回GetDesktopWindow()。因此,如果(HWND)::GetWindow(hwnd, GW_OWNER)应该返回顶级窗口的所有者,那么nullptr返回GetParent()时将从何处得到?

它确实与(HWND)::GetWindow(hwnd, GW_OWNER)一致,但这将表明它是一个子窗口,这对于许多窗口类被列为nullptr是有意义的。但是,我已经看到其他HWND在其应有的位置具有值,并且可能是基于上下文而只是忽略了该值。这些在某一时刻可能是非顶级窗口的另一个原因是(HWND)::GetWindowLongPtr(hwnd, GWLP_HWNDPARENT)返回ComboLBox

通过我所做的额外分析,看来某些应用程序正在以某种方式将非顶层窗口提升为顶层窗口,这表明存在某些错误或正在使用某些未记录/未定义的行为,并且会导致在奇数HWND链接中。

任何人都可以确认这些错误是由错误引起的,还是出于某些合理原因而正在执行的操作?

编辑

最小,完整和可验证的示例:

!(GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD)

示例输出:

false

1 个答案:

答案 0 :(得分:0)

具有父级但没有所有者的窗口不是顶层窗口。那是对您所描述的场景的显而易见的解释。

更新

似乎并非如此,因为您现在解释了窗口来自EnumWindows。它的文档说:

  

EnumWindows函数不枚举子窗口,但系统拥有的一些具有WS_CHILD样式的顶级窗口除外。

因此,我认为这些必须是您描述的窗口。那是系统拥有的顶级窗口,具有WS_CHILD样式。