• C# 获取指定窗口的上层窗口


     如何获取当前窗口层级上方的所有窗口信息

    User32有函数GetWindow function (winuser.h) - Win32 apps | Microsoft Docs,可以根据已知窗口句柄,获取指定类型的窗口。

    1     [DllImport("user32.dll", SetLastError = true)]
    2     public static extern IntPtr GetWindow(IntPtr hwnd, uint windowType);

    这里我们获取上层窗口:GW_HWNDPREV = 3

     1     public static List<WindowInfo> GetAllAboveWindows(IntPtr hwnd)
     2     {
     3         var windowInfos = new List<WindowInfo>();
     4         var intPtr = User32.GetWindow(hwnd, 3);
     5         if (intPtr == IntPtr.Zero)
     6         {
     7             return windowInfos;
     8         }
     9         var windowDetail = GetWindowDetail(intPtr);
    10         windowInfos.AddRange(GetAllAboveWindows(intPtr));
    11         windowInfos.Add(windowDetail);
    12         return windowInfos;
    13     }

    获取所有窗口,输出到测试窗口

     1     private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
     2     {
     3         var currentIntPtr = new WindowInteropHelper(this).Handle;
     4         var windows = WindowEnumerator.GetAllAboveWindows(new IntPtr(131450));
     5         var windowInfos = windows.Where(I => I.IsVisible && !I.IsMinimized && I.Bounds.Width > 1 && I.Bounds.Height > 1
     6                                         && I.Hwnd!= currentIntPtr).ToList();
     7         foreach (var windowInfo in windowInfos)
     8         {
     9             WindowsTextBlock.Text +=
    10                 $"Hwnd:{windowInfo.Hwnd},Title:{windowInfo.Title},IsMinimized:{windowInfo.IsMinimized},IsVisible:{windowInfo.IsVisible},ClassName:{windowInfo.ClassName},Bounds:{windowInfo.Bounds}\r\n";
    11         }
    12     }

    输出所有窗口信息如下 :

    由输出信息,可以了解到,任务栏是在所有非置顶窗口的最上方的。

    所以我们要除去任务栏:

    1     var windowInfos = windows.Where(I => I.IsVisible && !I.IsMinimized && I.Bounds.Width > 1 && I.Bounds.Height > 1
    2                                     && I.Hwnd!= currentIntPtr
    3                                     &&!(I.ClassName.StartsWith("Shell_") && I.ClassName.EndsWith("TrayWnd"))).ToList();

     User32相关函数:

     1     public static class User32
     2     {
     3         [DllImport("user32.dll", SetLastError = true)]
     4         public static extern IntPtr GetWindow(IntPtr hwnd, uint windowType);
     5 
     6         public delegate bool WndEnumProc(IntPtr hWnd, int lParam);
     7         [DllImport("user32")]
     8         public static extern bool EnumWindows(WndEnumProc lpEnumFunc, int lParam);
     9 
    10         [DllImport("user32")]
    11         public static extern IntPtr GetParent(IntPtr hWnd);
    12 
    13         [DllImport("user32")]
    14         public static extern bool IsWindowVisible(IntPtr hWnd);
    15 
    16         [DllImport("user32")]
    17         public static extern int GetWindowText(IntPtr hWnd, StringBuilder lptrString, int nMaxCount);
    18 
    19         [DllImport("user32")]
    20         public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
    21 
    22         [DllImport("user32")]
    23         public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
    24 
    25         [DllImport("user32")]
    26         public static extern bool GetWindowRect(IntPtr hWnd, ref LPRECT rect);
    27 
    28 
    29         [StructLayout(LayoutKind.Sequential)]
    30         public readonly struct LPRECT
    31         {
    32             public readonly int Left;
    33             public readonly int Top;
    34             public readonly int Right;
    35             public readonly int Bottom;
    36         }
    37     }
    38     /// <summary>
    39     /// 获取 Win32 窗口的一些基本信息。
    40     /// </summary>
    41     public readonly struct WindowInfo
    42     {
    43         public WindowInfo(IntPtr hWnd, string className, string title, bool isVisible, Rect bounds) : this()
    44         {
    45             Hwnd = hWnd;
    46             ClassName = className;
    47             Title = title;
    48             IsVisible = isVisible;
    49             Bounds = bounds;
    50         }
    51 
    52         /// <summary>
    53         /// 获取窗口句柄。
    54         /// </summary>
    55         public IntPtr Hwnd { get; }
    56 
    57         /// <summary>
    58         /// 获取窗口类名。
    59         /// </summary>
    60         public string ClassName { get; }
    61 
    62         /// <summary>
    63         /// 获取窗口标题。
    64         /// </summary>
    65         public string Title { get; }
    66 
    67         /// <summary>
    68         /// 获取当前窗口是否可见。
    69         /// </summary>
    70         public bool IsVisible { get; }
    71 
    72         /// <summary>
    73         /// 获取窗口当前的位置和尺寸。
    74         /// </summary>
    75         public Rect Bounds { get; }
    76 
    77         /// <summary>
    78         /// 获取窗口当前是否是最小化的。
    79         /// </summary>
    80         public bool IsMinimized => Bounds.Left == -32000 && Bounds.Top == -32000;
    81     }
    View Code

     WindowEnumerator测试类:

     1     /// <summary>
     2     /// 包含枚举当前用户空间下所有窗口的方法。
     3     /// </summary>
     4     public class WindowEnumerator
     5     {
     6         /// <summary>
     7         /// 查找当前用户空间下所有符合条件的窗口(仅查找顶层窗口)。如果不指定条件,将返回所有窗口。
     8         /// </summary>
     9         /// <param name="match">过滤窗口的条件。</param>
    10         /// <returns>找到的所有窗口信息。</returns>
    11         public static IReadOnlyList<WindowInfo> FindAll(Predicate<WindowInfo> match = null)
    12         {
    13             var windowList = new List<WindowInfo>();
    14             User32.EnumWindows(OnWindowEnum, 0);
    15             return match == null ? windowList : windowList.FindAll(match);
    16 
    17             bool OnWindowEnum(IntPtr hWnd, int lparam)
    18             {
    19                 // 仅查找顶层窗口。
    20                 if (User32.GetParent(hWnd) == IntPtr.Zero)
    21                 {
    22                     var windowDetail = GetWindowDetail(hWnd);
    23                     // 添加到已找到的窗口列表。
    24                     windowList.Add(windowDetail);
    25                 }
    26 
    27                 return true;
    28             }
    29         }
    30 
    31         private static WindowInfo GetWindowDetail(IntPtr hWnd)
    32         {
    33             // 获取窗口类名。
    34             var lpString = new StringBuilder(512);
    35             User32.GetClassName(hWnd, lpString, lpString.Capacity);
    36             var className = lpString.ToString();
    37 
    38             // 获取窗口标题。
    39             var lptrString = new StringBuilder(512);
    40             User32.GetWindowText(hWnd, lptrString, lptrString.Capacity);
    41             var title = lptrString.ToString().Trim();
    42 
    43             // 获取窗口可见性。
    44             var isVisible = User32.IsWindowVisible(hWnd);
    45 
    46             // 获取窗口位置和尺寸。
    47             User32.LPRECT rect = default;
    48             User32.GetWindowRect(hWnd, ref rect);
    49             var bounds = new Rect(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
    50 
    51             return new WindowInfo(hWnd, className, title, isVisible, bounds);
    52         }
    53         public static List<WindowInfo> GetAllAboveWindows(IntPtr hwnd)
    54         {
    55             var windowInfos = new List<WindowInfo>();
    56             var intPtr = User32.GetWindow(hwnd, 3);
    57             if (intPtr == IntPtr.Zero)
    58             {
    59                 return windowInfos;
    60             }
    61             var windowDetail = GetWindowDetail(intPtr);
    62             windowInfos.AddRange(GetAllAboveWindows(intPtr));
    63             windowInfos.Add(windowDetail);
    64             return windowInfos;
    65         }
    66         public static List<WindowInfo> GetAllBelowWindows(IntPtr hwnd)
    67         {
    68             var windowInfos = new List<WindowInfo>();
    69             var intPtr = User32.GetWindow(hwnd, 2);
    70             if (intPtr == IntPtr.Zero)
    71             {
    72                 return windowInfos;
    73             }
    74             var windowDetail = GetWindowDetail(intPtr);
    75             windowInfos.AddRange(GetAllBelowWindows(intPtr));
    76             windowInfos.Add(windowDetail);
    77             return windowInfos;
    78         }
    79     }
    View Code
  • 相关阅读:
    设置Centos7会话超时时间
    Shell浮点运算
    Maven 同一依赖多版本共存
    Java根据模板生成word
    Java条形码生成
    arcgis for js 4.x 悬浮显示popup
    tomcat 跨域配置
    Mysql8.0 版本 timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',报错
    volatile
    synchronized
  • 原文地址:https://www.cnblogs.com/kybs0/p/16010169.html
Copyright © 2020-2023  润新知