本文介绍了像 alt-tab 一样枚举窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm creating an alt-tab replacement for Vista but I have some problems listing all active programs.

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

I'm using EnumWindows to get a list of Windows, but this list is huge. It contains about 400 items when I only have 10 windows open. It seems to be a hwnd for every single control and a lot of other stuff.

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

So I have to filter this list somehow, but I can't manage to do it exactly as alt-tab does.

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

This is the code I use to filter the list right now. It works pretty well, but I get some unwanted windows like detached tool-windows in Visual Studio and I also miss windows like iTunes and 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;
}

推荐答案

Raymond Chen 不久前回答了这个问题
(https://devblogs.microsoft.com/oldnewthing/20071008-00/?p=24863):

Raymond Chen answered this a while back
(https://devblogs.microsoft.com/oldnewthing/20071008-00/?p=24863):

其实很简单几乎没有什么你能猜到的靠你自己.注:本次详情算法是一种实现细节.它可以随时改变,所以不要依赖它.事实上,它已经随 Flip 和 Flip3D 改变;我只是谈论经典的 Alt+Tab窗口在这里.

对于每个可见的窗口,向上走所有者链,直到找到根所有者.然后走回可见的最后一个活动的弹出链,直到你找到一个可见的窗口.如果你回到你开始的地方,然后把Alt+Tab 列表中的窗口.在伪代码:

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 的博客链接,了解更多详情和一些角落条件.

Follow the link to Chen's blog entry for more details and some corner conditions.

这篇关于像 alt-tab 一样枚举窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 08:25