c# - 像 alt-tab 一样枚举窗口

标签 c# windows winapi

我正在为 Vista 创建一个 alt-tab 替代品,但我在列出所有事件程序时遇到了一些问题。

我正在使用 EnumWindows 获取 Windows 列表,但这个列表很大。当我只打开 10 个窗口时,它包含大约 400 个项目。它似乎是每个控件和许多其他东西的 hwnd。

所以我必须以某种方式过滤此列表,但我无法像 alt-tab 那样完全做到这一点。

这是我现在用来过滤列表的代码。它工作得很好,但我得到了一些不需要的窗口,比如 Visual Studio 中的分离工具窗口,我也错过了像 iTunes 和 Warcraft3 这样的窗口。

private bool ShouldWindowBeDisplayed(IntPtr window)
{
    uint windowStyles = Win32.GetWindowLong(window, GWL.GWL_STYLE);

    if (((uint)WindowStyles.WS_VISIBLE & windowStyles) != (uint)WindowStyles.WS_VISIBLE ||
        ((uint)WindowExStyles.WS_EX_APPWINDOW & windowStyles) != (uint)WindowExStyles.WS_EX_APPWINDOW)
    {
        return true;
    }
    return false;
}

最佳答案

陈百强刚才回答过这个问题
( https://devblogs.microsoft.com/oldnewthing/20071008-00/?p=24863 ):

It's actually pretty simple although hardly anything you'd be able to guess on your own. Note: The details of this algorithm are an implementation detail. It can change at any time, so don't rely on it. In fact, it already changed with Flip and Flip3D; I'm just talking about the Classic Alt+Tab window here.

For each visible window, walk up its owner chain until you find the root owner. Then walk back down the visible last active popup chain until you find a visible window. If you're back to where you're started, then put the window in the Alt+Tab list. In pseudo-code:

BOOL IsAltTabWindow(HWND hwnd)
{
 // Start at the root owner
 HWND hwndWalk = GetAncestor(hwnd, GA_ROOTOWNER);

 // See if we are the last active visible popup
 HWND hwndTry;
 while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry) {
  if (IsWindowVisible(hwndTry)) break;
  hwndWalk = hwndTry;
 }
 return hwndWalk == hwnd;
}

点击 Chen 博客条目的链接,了解更多详细信息和一些边角条件。

关于c# - 像 alt-tab 一样枚举窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/210504/

相关文章:

c# - 如何使用 JQuery 获取母版页中控件的值?

c# - 如何比较两个列表并更改一个列表中的一个属性?

c# - 如何创建只加载到内存中一次的 C# 库?

c++ - 如何使用CreateWindowEx创建win7风格的按钮

windows - 如何在 Windows 中生成 OSD?

c++ - 基于对话框的 MFC 应用程序中的视觉样式?

c# - 如何在 F# 或 C# 中将像素绘制到位图上而不是抗锯齿点上?

c# - 枚举所有 "always on top"的窗口

c - 使用 DeviceIoControl 从应用程序向驱动程序发送数据

windows - 挂载 Windows 驱动器以从 Docker 访问