从几个初步测试开始,似乎EnumWindows
总是以反向实例化顺序返回窗口,即最近实例化的窗口.这是一个有效的观察吗?如果是这样,在所有版本的Windows中都是如此吗?这是一个可靠的假设,即某种行为记录在哪里?
上下文:我正在处理我触发第三方应用程序打开几个非模态窗口的情况,我需要在打开后向这些窗口发送一些窗口消息,但我没有确定的方式鉴定它们的窗口类别和它们的标题都不会有所不同,我也不知道它们的预期坐标.但是,如果我可以依赖上面的行为,EnumWindows
我可以简单地使用返回的第一个句柄,EnumWindows
其类和标题符合我的期望.这仍然留下一些假设的循环漏洞,但我认为这将是足够好的.尽管如此,欢迎另类建议.
它按Z顺序返回它们.首先是带有WS_EX_TOPMOST
set 的最顶层窗口,直到最底部的窗口WS_EX_TOPMOST set
,然后是最顶层的窗口,而不是WS_EX_TOPMOST
最底层的窗口WS_EX_TOPMOST
.请注意,可见性不是决定因素,因此Z序中比可见窗口更高的不可见窗口仍会出现在它之前.
编辑:
您不太可能按照自己的意愿使用它,只需从第一次返回即可EnumWindows
.您的新窗口不仅不是第一次返回,而且您还有一个竞争条件,在此期间可以打开其他窗口.但是,您可以为应用程序保留所有已知窗口的列表,当您需要查找新打开的窗口时,请调用EnumWindows
窗口句柄并将其与列表中的窗口句柄进行比较.当你找到一个具有正确的类和标题(你甚至可能检查它属于正确的进程GetWindowThreadProcessID
)的那个不在你的列表中时,你就找到了新的窗口.
但是,出于您的目的,您可以通过安装CBT挂钩并观察HCBT_CREATEWND通知来获得更好的服务.请参阅MSDN上的帮助SetWindowsHookEx()
,并在CBTProc
回调以获取更多信息.
关于枚举顺序的确定性程度:
这个问题的一些评论和其他答案提到MSDN中缺少关于EnumWindows
返回窗口处理顺序的精确文档.事实上,在页面上EnumWindows
,并在EnumWindowsProc
回调都对这个问题相当沉默.我提供以下证据:
甲C++ Q&在MSDN杂志的一篇文章确实状态具体为:
EnumWindows以自上而下的Z顺序枚举窗口
该页面提示EnumChildWindows
备注部分中的订单:
将在枚举过程中以Z顺序移动或重新定位的子窗口将被正确枚举.
这意味着订单依赖于Z顺序.因为,在hWndParent参数的描述中,它说:
如果此参数为NULL,则此函数等效于EnumWindows.
可以假设相同的逻辑和顺序适用于EnumWindows
.
这是此函数的可观察行为,这使得它改变它是一个重大变化.总的来说,微软一直非常善于不对可观察行为进行重大改变.这不是保证,但这是一个非常安全的赌注.您更有可能发现在下一个版本中,您正在使用的函数已被弃用 - 并替换为另一个"Ex"版本 - 而不是发现其可观察行为已更改.
当然,在这一点上,这一切都是非常学术性的,因为EnumWindows
可能不是解决OP问题的最佳解决方案 - 至少EnumThreadWindows
可能是更合适的 - 但我认为值得一提的是其他可能遇到此问题的人帖子.