从一些初步测试来看, EnumWindows 似乎总是以相反的实例化顺序返回窗口,即最近实例化的窗口在前。这是一个有效的观察结果吗?如果是这样,则在所有Windows版本中都适用吗?这是可靠的假设吗,即该行为是否记录在某处?

上下文:我正在处理以下情况:我触发第三方应用程序打开多个非模式窗口,并且一旦它们打开,我需要向这些窗口发送一些窗口消息,但是我无法确定将它们标识为它们的窗口类和标题都不会有所不同,我也不知道它们的预期坐标。但是,如果我可以依靠EnumWindows的上述行为,则可以简单地使用EnumWindows返回的第一个句柄,该句柄的类和标题与我的期望相符。这仍然留下了一些假设的漏洞,但我认为这已经足够了。尽管如此,欢迎提出其他建议。

最佳答案

它以Z顺序返回它们。首先是设置了WS_EX_TOPMOST的最上面的窗口,直到设置了WS_EX_TOPMOST set的最下面的窗口,然后是没有WS_EX_TOPMOST的最上面的窗口,直到没有WS_EX_TOPMOST的最下面的窗口。请注意,可见性不是决定性因素,因此在Z轴顺序上比可见窗口高的不可见窗口仍会出现在它之前。

编辑:

仅从EnumWindows获得第一笔 yield 就极不可能随意使用它。您的新窗口不仅不大可能成为第一个返回窗口,而且您还处于竞争状态,在此期间可能会打开其他窗口。但是,您可以保留该应用程序所有已知窗口的列表,当需要查找新打开的窗口时,请调用EnumWindows并将窗口句柄与列表中的句柄进行比较。当找到不在列表中的具有正确的类和标题(甚至可以使用GetWindowThreadProcessID甚至检查它是否属于正确的进程)的标题时,便找到了新窗口。

但是,出于您的目的,安装CBT挂钩并注意HCBT_CREATEWND通知可能会为您提供更好的服务。有关更多信息,请参见 SetWindowsHookEx() the CBTProc callback上的MSDN帮助。

关于枚举顺序的确定性级别:

关于此问题的许多评论和其他答案都提到了MSDN中缺少EnumWindows返回窗口句柄的顺序的精确文档。实际上,关于 EnumWindows the EnumWindowsProc callback的页面都对此问题保持沉默。我提供以下证据:

  • C++ Q&A article in MSDN magazine确实声明:

  • EnumChildWindows 上的页面暗指备注部分中的顺序:



    这意味着该顺序是Z顺序相关的。并且由于在hWndParent参数的描述中这样说:



    可以假设EnumWindows采用相同的逻辑和顺序。
  • 这是此函数的可观察到的行为,因此对其进行更改是一项重大更改。总体而言,Microsoft对于不对可见行为进行重大更改一直非常擅长。那不是保证,但这是一个非常安全的选择。与发现其可观察到的行为已发生变化相比,您更有可能发现在下一版本中,您正在使用的功能已被弃用(并替换为另一个“Ex”版本)。

  • 当然,这一点在学术上都是很学术的,因为EnumWindows可能不是解决OP问题的最佳解决方案-至少EnumThreadWindows可能更合适-但是我认为值得其他人提及在这篇文章中

    关于windows - EnumWindows返回句柄的顺序有意义吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/295996/

    10-11 15:06