C# 判断窗体是否被遮挡,是否完全显示
思路:
1.获取显示在需判断窗体之上的其他窗体(一个或多个)
2.获取这些窗体的矩形信息
3.判断这些窗体和需判断窗体的矩形是否相交
4.处理一些特殊情况,如任务栏和开始按钮(可略过)
适用场景:在窗体失去焦点的情况下,判断窗体是否显示完全
具体代码如下:
namespace WindowTimeDev { using System; using System.Windows.Forms; using System.Drawing; using System.Runtime.InteropServices; using System.Diagnostics; using System.Collections.Generic; [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; public Rectangle ToRectangle() { return new Rectangle(Left, Top, Right - Left, Bottom - Top); } } public static class FormHelper { private static List<Rectangle> ScreenRectangles = new List<Rectangle>(); static FormHelper() { foreach (var screen in Screen.AllScreens) { ScreenRectangles.Add(screen.WorkingArea); } } /// <summary> /// 判断窗体是否被遮挡 /// </summary> /// <param name="form">被判断的窗体</param> /// <returns>true 被遮挡;false 没被遮挡</returns> public static bool IsOverlapped(Form form) { return isoverlapped(form.Handle, form); } [DllImport("user32.dll")] private static extern IntPtr GetWindow(IntPtr hWnd, uint wWcmd); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect); private static bool isoverlapped(IntPtr win, Form form) { IntPtr preWin = GetWindow(win, 3); //获取显示在Form之上的窗口 if (preWin == null || preWin == IntPtr.Zero) return false; if (!IsWindowVisible(preWin)) return isoverlapped(preWin, form); RECT rect = new RECT(); if (GetWindowRect(preWin, ref rect)) //获取窗体矩形 { Rectangle winrect = rect.ToRectangle(); var sceenRect = ScreenRectangles.Find(x => x.Width == winrect.Width); if (sceenRect != null) { if (winrect.Y + winrect.Height == sceenRect.Height || winrect.Y == sceenRect.Height) //任务栏。不判断遮挡 { Debug.WriteLine("任务栏,不判断遮挡"); return isoverlapped(preWin, form); } } if (winrect.X == 0 && winrect.Y == 0 && winrect.Width == 1 && winrect.Height == 1) //特殊窗体,不判断遮挡 { Debug.WriteLine("特殊窗体"); return isoverlapped(preWin, form); } Rectangle formRect = new Rectangle(form.Location, form.Size); //Form窗体矩形 if (formRect.IntersectsWith(winrect)) //判断是否遮挡 { Debug.WriteLine($"被该窗体遮挡 {winrect}"); return true; } } return isoverlapped(preWin, form); } [DllImport("user32.dll")] private static extern bool IsWindowVisible(IntPtr hWnd); } }
在窗体中使用时的代码如下:
if(FormHelper.IsOverlapped(this)) { //具体操作,比如把窗口显示到前台 }