Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 像alt tab一样枚举窗口_C#_Windows_Winapi - Fatal编程技术网

C# 像alt tab一样枚举窗口

C# 像alt tab一样枚举窗口,c#,windows,winapi,C#,Windows,Winapi,我正在为Vista创建替换的alt选项卡,但在列出所有活动程序时遇到一些问题 我正在使用EnumWindows获取一个窗口列表,但是这个列表很大。当我只打开10个窗口时,它包含大约400个项目。它似乎是一个hwnd为每一个单一的控制和许多其他东西 因此,我必须以某种方式筛选此列表,但我无法完全按照alt tab的方式进行筛选 这是我现在用来过滤列表的代码。它工作得很好,但我有一些不需要的窗口,比如VisualStudio中的分离工具窗口,我也怀念iTunes和Warcraft3等窗口 priva

我正在为Vista创建替换的alt选项卡,但在列出所有活动程序时遇到一些问题

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

因此,我必须以某种方式筛选此列表,但我无法完全按照alt tab的方式进行筛选

这是我现在用来过滤列表的代码。它工作得很好,但我有一些不需要的窗口,比如VisualStudio中的分离工具窗口,我也怀念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;
}

陈雷蒙不久前回答了这个问题
():

其实很简单 你几乎猜不到什么 靠你自己。注:详情如下: 算法是一种实现 细节它可以随时改变,所以 不要依赖它。事实上,它已经存在了 使用Flip和Flip3D进行更改;我只是 谈论经典的Alt+Tab 这里是窗户

对于每个可见窗口,向上走 所有者链,直到找到根为止 主人。然后,沿着可见的道路往回走 最后一个激活的弹出链,直到找到 可见的窗口。如果你回到家里 从哪里开始,然后把 在Alt+选项卡列表中的窗口。在里面 伪代码:

有关更多详细信息和一些转角条件,请点击陈的博客链接。

谢谢Mike B。 Raymonds博客上的例子为我指明了正确的方向

不过,也有一些例外情况,Windows Live messenger因在Windows下创建阴影等而遭到大量黑客攻击:@

这是我的完整代码,我已经用了一天了,没有注意到它和真正的alt标签有什么不同。有一些底层代码没有发布,但弄清楚它的功能并没有问题。:)


这是pascal/delphi中的一个函数,您可以轻松地将其转换为C

它包括对Windows 10应用程序的支持


EnumWindows(@ListApps,0);
函数ListApps(LHWindow:HWND;lParam:Pointer):布尔;stdcall;
变量
lhnd;
LH父母:HWND;
词汇风格:德沃德;
AppClassName:字符的数组[0..255];
斗篷:红衣主教;
titlelen:整数;
标题:字符串;
开始
LHDesktop:=GetDesktopWindow;
GetClassName(LHWindow,AppClassName,255);
LHParent:=GetWindowLong(LHWindow,GWL\uHwndParent);
LExStyle:=GetWindowLong(LHWindow,GWL_EXSTYLE);
如果AppClassName='ApplicationFrameWindow',则
DwmGetWindowAttribute(左窗,DWMWA_斗篷,@斗篷,sizeof(红衣主教))
其他的
隐身:=DWM_普通_应用_未隐身;
如果IsWindow可见(LHWindow)
和(AppClassName'Windows.UI.Core.CoreWindow')
和((隐身=DWM_未隐身)或(隐身=DWM_正常_应用_未隐身))
和((LHParent=0)或(LHParent=LHDesktop))
和(应用程序。HandleLHWindow)
和((LExStyle和WS_-EX_-TOOLWINDOW=0)或(LExStyle和WS_-EX_-APPWINDOW 0))
然后
开始
titlelen:=GetWindowTextLength(LHWindow);
设置长度(标题、标题栏);
GetWindowText(LHWindow,PChar(标题),标题栏+1);
{将每个添加到列表中}
但是.ListBox1.Items.Add(title);
{也将每个HWND添加到列表中,稍后使用SwitchToThisWindow切换}
{ ... }
结束;
结果:=真;
结束;

干得好vhanla。我的Pascal有点生疏,但你的解决方案帮了大忙。我是新手,所以请原谅我的代码和/或表达方式。答案相对简单

要创建Alt选项卡窗口列表,似乎需要三个条件

1) 窗口必须可见-使用GetWindowVisible

2) 窗口不能是工具栏窗口-使用GetWindowInfo

3) 不得遮盖车窗-使用DwmGetWindowAttribute

我不认为你需要看类名。我认为WS_EX_APPWINDOW标志经常会失败(例如Chrome)——即使与WS_EX_TOOLWINDOW一起使用也是如此。也。。。如果在顶层枚举窗口,我认为不需要查看父窗口

    public static bool IsAltTabWindow(IntPtr hWnd)
    {
        const uint WS_EX_TOOLWINDOW = 0x00000080;
        const uint DWMWA_CLOAKED = 14;

        //  It must be a visible Window
        if (!IsWindowVisible(hWnd)) return false;

        //  It must not be a Tool bar window
        WINDOWINFO winInfo = new WINDOWINFO(true);
        GetWindowInfo(hWnd, ref winInfo);            
        if ((winInfo.dwExStyle & WS_EX_TOOLWINDOW) != 0) return false;

        //  It must not be a cloaked window
        uint CloakedVal;
        DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, out CloakedVal, sizeof(uint));
        return CloakedVal == 0;
    }

“窗口信息”来自哪里?我已经用谷歌搜索了很多方法,但没有发现任何有用的东西。它是自定义类型吗?您可以使用:请注意,此实现不支持Raymond的博客文章中提到的
WS_EX_TOOLWINDOW
WS_EX_APPWINDOW
扩展样式。这里有一个基于此方法的更完整和健壮的示例,它来自另一个alt tab实用程序,这似乎准确地显示了常规alt选项卡菜单的功能。要检测UWP应用程序,请检查“ApplicationFrameWindow”窗口类名称,然后使用
dwmGetWindow属性(LHWindow,DWMWA_斗篷,@斗篷,sizeof(基数))
对其进行求值,如果
cloacked
(整数)返回0,则表示UWP应用程序未隐藏。
    private static bool KeepWindowHandleInAltTabList(IntPtr window)
    {
        if (window == Win32.GetShellWindow())   //Desktop
            return false;

        //http://stackoverflow.com/questions/210504/enumerate-windows-like-alt-tab-does
        //http://blogs.msdn.com/oldnewthing/archive/2007/10/08/5351207.aspx
        //1. For each visible window, walk up its owner chain until you find the root owner. 
        //2. Then walk back down the visible last active popup chain until you find a visible window.
        //3. If you're back to where you're started, (look for exceptions) then put the window in the Alt+Tab list.
        IntPtr root = Win32.GetAncestor(window, Win32.GaFlags.GA_ROOTOWNER);

        if (GetLastVisibleActivePopUpOfWindow(root) == window)
        {
            WindowInformation wi = new WindowInformation(window);

            if (wi.className == "Shell_TrayWnd" ||                          //Windows taskbar
                wi.className == "DV2ControlHost" ||                         //Windows startmenu, if open
                (wi.className == "Button" && wi.windowText == "Start") ||   //Windows startmenu-button.
                wi.className == "MsgrIMEWindowClass" ||                     //Live messenger's notifybox i think
                wi.className == "SysShadow" ||                              //Live messenger's shadow-hack
                wi.className.StartsWith("WMP9MediaBarFlyout"))              //WMP's "now playing" taskbar-toolbar
                return false;

            return true;
        }
        return false;
    }

    private static IntPtr GetLastVisibleActivePopUpOfWindow(IntPtr window)
    {
        IntPtr lastPopUp = Win32.GetLastActivePopup(window);
        if (Win32.IsWindowVisible(lastPopUp))
            return lastPopUp;
        else if (lastPopUp == window)
            return IntPtr.Zero;
        else
            return GetLastVisibleActivePopUpOfWindow(lastPopUp);
    }
    public static bool IsAltTabWindow(IntPtr hWnd)
    {
        const uint WS_EX_TOOLWINDOW = 0x00000080;
        const uint DWMWA_CLOAKED = 14;

        //  It must be a visible Window
        if (!IsWindowVisible(hWnd)) return false;

        //  It must not be a Tool bar window
        WINDOWINFO winInfo = new WINDOWINFO(true);
        GetWindowInfo(hWnd, ref winInfo);            
        if ((winInfo.dwExStyle & WS_EX_TOOLWINDOW) != 0) return false;

        //  It must not be a cloaked window
        uint CloakedVal;
        DwmGetWindowAttribute(hWnd, DWMWA_CLOAKED, out CloakedVal, sizeof(uint));
        return CloakedVal == 0;
    }