我一直在研究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.exe
和ComboLBox
,explorer.exe
,notepad++.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
答案 0 :(得分:0)
具有父级但没有所有者的窗口不是顶层窗口。那是对您所描述的场景的显而易见的解释。
更新
似乎并非如此,因为您现在解释了窗口来自EnumWindows
。它的文档说:
EnumWindows函数不枚举子窗口,但系统拥有的一些具有WS_CHILD样式的顶级窗口除外。
因此,我认为这些必须是您描述的窗口。那是系统拥有的顶级窗口,具有WS_CHILD样式。