问题描述
我正在为 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 一样枚举窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!