主要是获取Alt+Tab中展示的窗口
原理主要是获取窗口的样式来判断是否会在Alt+Tab中显示
具体代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /// /// Alt+Tab 应用 /// /// /// public static bool IsAltTabWindow(IntPtr hWnd) { // The window must be visible if (!IsWindowVisible(hWnd)) return false ; // The window must be a root owner if (GetAncestor(hWnd, GA_ROOTOWNER) != hWnd) return false ; // The window must not be cloaked by the shell DwmGetWindowAttribute(hWnd, DwmWindowAttribute.DWMWA_CLOAKED, out int cloaked, sizeof ( uint )); if (cloaked == DWM_CLOAKED_SHELL) return false ; // The window must not have the extended style WS_EX_TOOLWINDOW int style = Utils.Win32Api.GetWindowLong(hWnd, GWL_EXSTYLE); if ((style & WS_EX_TOOLWINDOW) != 0) return false ; return true ; } [DllImport( "User32.dll" , CharSet = CharSet.Auto)] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport( "user32.dll" )] public static extern IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); [DllImport( "dwmapi.dll" )] public static extern int DwmGetWindowAttribute(IntPtr hwnd, DwmWindowAttribute dwAttribute, out int attrValue, int cbAttribute); const uint DWM_CLOAKED_SHELL = 0x00000002; const uint GA_ROOTOWNER = 3; const uint WS_EX_TOPMOST = 0x00000008; [Flags] public enum DwmWindowAttribute : uint { DWMWA_NCRENDERING_ENABLED = 1, DWMWA_NCRENDERING_POLICY, DWMWA_TRANSITIONS_FORCEDISABLED, DWMWA_ALLOW_NCPAINT, DWMWA_CAPTION_BUTTON_BOUNDS, DWMWA_NONCLIENT_RTL_LAYOUT, DWMWA_FORCE_ICONIC_REPRESENTATION, DWMWA_FLIP3D_POLICY, DWMWA_EXTENDED_FRAME_BOUNDS, DWMWA_HAS_ICONIC_BITMAP, DWMWA_DISALLOW_PEEK, DWMWA_EXCLUDED_FROM_PEEK, DWMWA_CLOAK, DWMWA_CLOAKED, DWMWA_FREEZE_REPRESENTATION, DWMWA_LAST } /// /// 获取窗体句柄 /// /// /// /// [DllImport( "user32.dll" , EntryPoint = "GetWindowLongA" , SetLastError = true )] public static extern int GetWindowLong(IntPtr hwnd, int nIndex); const int GWL_EXSTYLE = -20; //得到扩展的窗口风格 public const int WS_EX_TOOLWINDOW = 0x00000080; |
以上方式对于全屏的UWP窗口时无法获取得到的,因此需要引入以下方式获取全屏UWP窗口
////// 全屏的UWP应用 /// /// /// public static bool IsFullScreenUwpWindows(IntPtr hWnd) { // Get the extended style of the window var style = GetWindowLong(hWnd, GWL_EXSTYLE); // The window must have the extended style WS_EX_TOPMOST if ((style & WS_EX_TOPMOST) == 0) return false; // The window must not have the extended style WS_EX_NOACTIVATE if ((style & WS_EX_NOACTIVATE) != 0) return false; // The window must not have the extended style WS_EX_TOOLWINDOW if ((style & WS_EX_TOOLWINDOW) != 0) return false; return true; } public const int WS_EX_NOACTIVATE = 0x08000000;
然后通过枚举窗口的方式就可以获取到所有窗口了
////// 枚举窗体的回调 /// /// /// /// public delegate bool EnumWindowsCallBack(IntPtr hwnd, IntPtr lParam); /// /// 枚举出窗体 /// /// /// /// [DllImport("user32")] public static extern int EnumWindows(EnumWindowsCallBack x, IntPtr y); /// /// 枚举子窗口 /// /// /// /// /// [DllImport("user32")] public static extern int EnumChildWindows(IntPtr hWndParent, EnumWindowsCallBack x, IntPtr y); List string>> handles = new List string>>(); EnumWindows((hWnd, lPam) => { if (!IsAltTabWindow(hWnd)) return true;//继续枚举 var title = GetWindowTitle(hWnd); handles.Add(new KeyValuePair string>(hWnd, title)); return true;//继续枚举 }, IntPtr.Zero); EnumChildWindows(GetDesktopWindow(), (hWnd, lPam) => { if (handles.Any(kv => kv.Key == hWnd)||!IsFullScreenUwpWindows(hWnd)) return true;//继续枚举 var title = GetWindowTitle(hWnd); handles.Add(new KeyValuePair string>(hWnd, title)); return true;//继续枚举 }, IntPtr.Zero); [DllImport("user32.dll")] public static extern IntPtr GetDesktopWindow(); /// /// 获取窗体的名称 /// /// /// /// /// [DllImport("user32.dll")] public static extern int GetWindowTextW(IntPtr hWnd, IntPtr lpString, int nMaxCount); /// /// 默认获取字符串的长度 /// private const int NumChars = 256; public static string GetWindowTitle(IntPtr hwnd) { IntPtr intPtr = Marshal.AllocHGlobal(NumChars); Utils.Win32Api.GetWindowTextW(hwnd, intPtr, 100); var s = Marshal.PtrToStringUni(intPtr); Marshal.FreeHGlobal(intPtr); return s; }
以上代码需要做调整才能运行起来,有空我补上完整代码
参考:https://stackoverflow.com/questions/72069771/show-a-list-of-all-alttab-windows-even-full-screen-uwp-windows-and-retrieve