小编use*_*019的帖子

Win32:按真实激活顺序枚举真实窗口

我现在已经厌倦了研究这个话题。系统中有上百万个 API 来实现部分功能,即枚举所有窗口,但没有涉及如何获取它们的真实 z 顺序。怎么做?让我解释。

首先,当然,要枚举窗口,可以使用EnumWindows或 当它表现不佳并决定不显示 UWP 应用程序时,因为操作系统中存在一些愚蠢的限制,可以直接使用NtUserBuildHwndList无论如何在后端调用的EnumWindows.

这样一来,您就可以在回调中过滤子窗口、隐藏窗口和奇怪的窗口。根据您所做的事情,您会得到不同的结果。为了让您免于阅读,最常见的方法是 Raymond Chen 那种过时的解决方案,或者尝试一些更新的方法,可以更好地过滤 Windows 10+ 中的隐藏窗口,并DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &bIsCloaked, sizeof(BOOL));用BOOL bIsCloaked = TRUE;您最终会得到真正的窗口对桌面感兴趣。

唯一的问题是,它们是按 z 顺序排序的。该列表是通过按 z 顺序对每个窗口带中的所有窗口进行排序而形成的,然后将结果连接到最终列表中。现在,什么是窗带?这是一项未记录的微软发明,他们让一些窗口位于更上面的位置HWND_TOPMOST(从安全角度来看是有道理的,但从根本不记录它的意义上来说,这是没有意义的)。您可以在这里阅读相关内容。基本上,桌面上有多个带区,每个带区是一组共享 z 顺序的窗口。然后,将条带堆叠在一起,生成条带的 z 顺序。选中“始终在顶部”的任务管理器在ZBID_SYSTEM_TOOLS上方的带区中运行ZBID_DESKTOP,这就是为什么它始终位于常规应用程序可以创建的任何窗口的顶部。

这是完全有道理的,但用户并不关心窗口带。它会看到桌面上的窗口,当按下 Alt-Tabing 时,它会看到一个按降序排列的列表,从最近使用的窗口到最后使用的窗口。按照这个顺序,尽管有乐队。例如,我的工作流程是 Firefox-Task Manager-cmd,我希望在 Alt-Tab 中看到 cmd-Task Manager-Firefox,尽管任务管理器始终位于顶部。

现在很明显,我们需要以某种方式对这个列表进行排序。出现的问题是,如何不考虑窗口带而按 z 顺序对窗口列表进行排序?我一生都无法在任何地方找到任何有用的东西,无论是在谷歌上,还是在乏善可陈的文档中。GetTopWindow并且GetNextWindow,传统功能比方说,始终将来自其他带的窗口放在第一个位置ZBID_DESKTOP,然后对其余窗口进行正确排序ZBID_DESKTOP。所有旧版 API 的行为就像其他频段中的窗口一样HWND_TOPMOST,这是有道理的。但我不希望这样:仅当我们一起考虑所有频带或所有窗口都在同一频带上时,z 顺序 …

winapi hwnd z-order

5
推荐指数
0
解决办法
446
查看次数

标签 统计

hwnd ×1

winapi ×1

z-order ×1