windows - EnumWindows 返回句柄的顺序有意义吗?

标签 windows winapi enumeration hwnd

从几个初步测试看来 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双方在这个问题上都保持沉默。我提供以下证据:

  1. A C++ Q&A article in MSDN magazine具体说明:

    EnumWindows enumerates the windows in top-down Z-order

  2. 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

  3. 这是此函数的可观察行为,因此更改它是一项重大更改。总的来说,Microsoft 在不对可观察到的行为进行重大更改方面做得很好。这不是保证,但这是一个非常安全的赌注。您更有可能发现在下一个版本中您正在使用的函数已被弃用——并被另一个“Ex”版本取代——而不是发现其可观察到的行为发生了变化。

当然,目前这一切都非常学术,因为 EnumWindows 可能不是解决 OP 问题的最佳解决方案——至少 EnumThreadWindows 可能是更合适——但我认为值得一提的是其他可能会看到这篇文章的人。

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

相关文章:

c# - 确定枚举值是否不是 C# 中的复合值

java - 我的枚举有什么问题?

windows - 如何修复此 Azure 错误 : web role unable to start after disabling remote desktop connections?

windows - 如何创建目录的快捷方式以便它在资源管理器中打开

c++ - GCC 和 MinGW (C++) 之间奇怪的输出差异

windows - Windbg 故障转储中的性能计数器

Ctrl + Shift +零的WPF KeyBinding Guesture不起作用

windows - Windows Creators 版本更新后 ExtTextOut 50 在 QHD/4K 屏幕上的性能下降

c++ - 如何在 WM_COMMAND 中检索鼠标位置

C (gnu11) enum 变量无法与 int 进行比较?