3

获取Windows正在运行的窗口进程 - 黄高林

 2 years ago
source link: https://www.cnblogs.com/Koalin/p/16633060.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

获取Windows正在运行的窗口进程

主要是获取Alt+Tab中展示的窗口

原理主要是获取窗口的样式来判断是否会在Alt+Tab中显示

具体代码如下

/// <summary>
/// Alt+Tab 应用
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
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
}
/// <summary>
/// 获取窗体句柄
/// </summary>
/// <param name="hwnd"></param>
/// <param name="nIndex"></param>
/// <returns></returns>
[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窗口

/// <summary>
        /// 全屏的UWP应用
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        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;

然后通过枚举窗口的方式就可以获取到所有窗口了

/// <summary>
        /// 枚举窗体的回调
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        public delegate bool EnumWindowsCallBack(IntPtr hwnd, IntPtr lParam);
        /// <summary>
        /// 枚举出窗体
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [DllImport("user32")]
        public static extern int EnumWindows(EnumWindowsCallBack x, IntPtr y);

 /// <summary>
        /// 枚举子窗口
        /// </summary>
        /// <param name="hWndParent"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [DllImport("user32")]
        public static extern int EnumChildWindows(IntPtr hWndParent, EnumWindowsCallBack x, IntPtr y);
 List<KeyValuePair<IntPtr, string>> handles = new List<KeyValuePair<IntPtr, string>>();
            EnumWindows((hWnd, lPam) =>
            {
                if (!IsAltTabWindow(hWnd)) return true;//继续枚举
                var title = GetWindowTitle(hWnd);
                handles.Add(new KeyValuePair<IntPtr, 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<IntPtr, string>(hWnd, title));
                return true;//继续枚举
            }, IntPtr.Zero);







[DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
/// <summary>
        /// 获取窗体的名称
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="lpString"></param>
        /// <param name="nMaxCount"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern int GetWindowTextW(IntPtr hWnd, IntPtr lpString, int nMaxCount);

/// <summary>
        /// 默认获取字符串的长度
        /// </summary>
        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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK