从几个初步测试看来 EnumWindows
总是以相反的实例化顺序返回窗口,即最近实例化的窗口最先。这是一个有效的观察吗?如果是这样,是否适用于所有版本的 Windows?这是一个可靠的假设吗,即该行为是否记录在某处?
上下文:我正在处理这样一种情况,我正在触发第三方应用程序打开几个非模态窗口,我需要在这些窗口打开后向它们发送一些窗口消息,但我没有可靠的方法来识别它们,因为它们的窗口类和标题都不会不同,而且我也不知道它们的预期坐标。但是,如果我可以依赖 EnumWindows
的上述行为,我可以简单地使用 EnumWindows
返回的第一个句柄,其类和标题符合我的期望。这仍然留下了一些假设的循环漏洞,但我认为它已经足够好了。尽管如此,还是欢迎其他建议。
最佳答案
它以 Z 顺序返回它们。首先是设置了 WS_EX_TOPMOST
的最顶层窗口,直到设置了 WS_EX_TOPMOST
的最底层窗口,然后是没有设置 WS_EX_TOPMOST
的最顶层窗口,尽管到没有 WS_EX_TOPMOST
的最底部窗口。请注意,可见性不是决定因素,因此在 Z 顺序上比可见窗口更高的不可见窗口仍会出现在它之前。
编辑:
您不太可能随意使用它,只需从 EnumWindows
获取第一个返回值。您的新窗口不仅不太可能成为第一个返回窗口,而且您会遇到竞争条件,同时可能会打开其他窗口。但是,您可以保留应用程序所有已知窗口的列表,当您需要查找新打开的窗口时,调用 EnumWindows
并将窗口句柄与列表中的句柄进行比较。当您找到一个具有正确的类和标题(您甚至可以使用 GetWindowThreadProcessID
检查它是否属于正确的进程)但不在您的列表中时,您我们找到了新窗口。
不过,为了您的目的,您可以通过安装 CBT Hook 并观察 HCBT_CREATEWND 通知来获得更好的服务。请参阅 SetWindowsHookEx()
上的 MSDN 帮助和 the CBTProc
callback获取更多信息。
枚举顺序的确定性级别:
这个问题的许多评论和其他答案都提到 MSDN 中缺乏关于 EnumWindows
返回窗口句柄的顺序的精确文档。事实上,EnumWindows
上的页面和 the EnumWindowsProc
callback双方在这个问题上都保持沉默。我提供以下证据:
A C++ Q&A article in MSDN magazine具体说明:
EnumWindows enumerates the windows in top-down Z-order
EnumChildWindows
上的页面暗指备注部分的顺序:A child window that is moved or repositioned in the Z order during the enumeration process will be properly enumerated.
这意味着顺序依赖于 Z 顺序。因为,在 hWndParent 参数的描述中,它是这样说的:
If this parameter is NULL, this function is equivalent to EnumWindows.
可以假设相同的逻辑和顺序适用于
EnumWindows
。- 这是此函数的可观察行为,因此更改它是一项重大更改。总的来说,Microsoft 在不对可观察到的行为进行重大更改方面做得很好。这不是保证,但这是一个非常安全的赌注。您更有可能发现在下一个版本中您正在使用的函数已被弃用——并被另一个“Ex”版本取代——而不是发现其可观察到的行为发生了变化。
当然,目前这一切都非常学术,因为 EnumWindows
可能不是解决 OP 问题的最佳解决方案——至少 EnumThreadWindows
可能是更合适——但我认为值得一提的是其他可能会看到这篇文章的人。
关于windows - EnumWindows 返回句柄的顺序有意义吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/295996/