EnumWindows返回句柄的顺序是否有意义?

从几个初步的testing看来, EnumWindows总是以反向实例顺序返回窗口,即最近实例化的窗口。 这是一个有效的观察? 如果是这样,所有版本的Windows都是真的吗? 这是一个可靠的假设,也就是说,行为logging在某个地方?


上下文: 我正在处理的情况是,我正在触发第三方应用程序来打开几个非模式窗口,我需要发送一些窗口消息到这些窗口打开,但我没有确定的方式确定他们的窗口类别和他们的标题不会有所不同,我也不知道他们的预期坐标。 但是,如果我可以依靠EnumWindows的上述行为,我可以简单地使用由EnumWindows返回的第一个句柄,它们的类和标题符合我的期望。 这仍然留下一些假设的循环漏洞,但我认为这将是足够好的。 不过,欢迎提供其他build议。

Solutions Collecting From Web of "EnumWindows返回句柄的顺序是否有意义?"

它以Z顺序返回它们。 首先设置WS_EX_TOPMOST的最顶层窗口,直到WS_EX_TOPMOST设置最底部的窗口,然后是没有WS_EX_TOPMOST的最顶层窗口,尽管到最底部的窗口没有WS_EX_TOPMOST 请注意,能见度不是一个决定性的因素,所以一个Z轴高于一个可见窗口的隐形窗口仍然会出现在它之前。

编辑

这是不太可能的,你可以使用这个你想要的,只是从EnumWindows的第一个返回。 不仅是你的新窗口不太可能成为第一个回报,而且还有其他窗口可以在此期间打开的竞赛状态。 但是,您可以保留应用程序的所有已知窗口的列表,当您需要查找新打开的窗口时,请调用EnumWindows并将窗口句柄与列表中的窗口句柄进行比较。 当你找到一个不在列表中的正确的类和标题(你甚至可以检查它是否属于正确的进程),那么你已经找到了新的窗口。

但是,出于您的目的,您可能会更好地通过安装CBT挂钩并观看HCBT_CREATEWND通知。 有关更多信息,请参阅SetWindowsHookEx()CBTProc回调上的MSDN帮助。

枚举顺序的确定性级别

这个问题的一些评论和其他答案提到了MSDN中关于EnumWindows返回窗口句柄的顺序的精确文档。 实际上, EnumWindows上的页面和EnumWindowsProc回调在这个问题上都相当沉默。 我提供以下证据:

  1. MSDN杂志中的一篇C ++ Q&A文章明确指出:

    EnumWindows按照从上到下的顺序枚举窗口

  2. EnumChildWindows上的页面暗示在备注部分的顺序:

    在枚举过程中,按Z顺序移动或重新定位的子窗口将被正确列举。

    这意味着顺序依赖于Z顺序。 而且,因为在hWndParent参数的描述中,它说:

    如果此参数为NULL,则此函数与EnumWindows等效。

    人们可以假定相同的逻辑和顺序适用于EnumWindows

  3. 这是这个函数的可观察的行为,这是改变它的一个重大改变。 一般来说,微软一直很擅长不对可观察到的行为做出重大改变。 这不是一个保证,但这是一个相当安全的赌注。 您更可能发现在下一个版本中,您正在使用的函数已被弃用,并被替换为另一个“Ex”版本,而不是发现其可观察行为已经改变。

当然,在这一点上,这是非常有学问的,因为EnumWindows可能不是解决OP问题的最佳解决方案 – 至少EnumThreadWindows可能会更合适 – 但我认为值得一提的是其他人可能会来在这篇文章中。

以前的答案需要相当的细化。 仅当GetSystemMetrics(SM_IMMENABLED)= 0时,Enum-order = Z顺序,即输入法管理器/输入法编辑器功能被禁用。 由于所有窗口类“IME”(标题“默认IME”)和“MSCTFIME UI”在窗口“Progman”(“程序管理器”)之后枚举,即不是Z顺序。

订单没有在API( MSDN链接 )中指定,所以不能保证是特别的东西 – 如果有保证,它将在API中明确指定。 例如,如果在枚举的中途创建了一个窗口,它会包含在枚举中呢? 这允许窗口管理者自由地改变它的实现,如果它变得更有效率的话。

但是,有一个独特的值可以用来区分窗口 – 窗口句柄本身。 在您的EnumWindowProc方法中,保存每个匹配窗口的窗口句柄 – 无论如何您都需要将消息发送到窗口。

如果你同时控制两个进程,你可以从第一个参数发送一个带有“HWND_BROADCAST”的SendMessage消息。

那么接收到msg的其他程序时,可以给他的子窗口做一个SendMessage。

如果文件没有说明枚举的顺序,我强烈建议你远离任何假设。 Raymond Chen的博客(blogs.msdn.com/oldnewthing)上的一些帖子会告诉你有多少应用程序依赖于所有这些无证的东西/观察,而当新版本的Windows出来时,有些事情会非常错误(除非MS开发人员又推出了另一个适用于另一个表现不佳的应用程序)。

至于你的目的,有几个函数,如GetWindowThreadProcessID,GetParent,EnumThreadWindows和EnumWindows,可以帮助您实现任务。