C# 判断窗体是否被遮挡,是否完全显示

思路:

1.获取显示在需判断窗体之上的其他窗体(一个或多个)

2.获取这些窗体的矩形信息

3.判断这些窗体和需判断窗体的矩形是否相交

4.处理一些特殊情况,如任务栏和开始按钮(可略过)

适用场景:在窗体失去焦点的情况下,判断窗体是否显示完全

具体代码如下:

using System.Runtime.InteropServices;
using System;
using System.Windows.Forms;
using System.Drawing;

namespace WindowTimeDev
{
    public static class FormHelper
    {
        static Rectangle ScreenRectangle = Rectangle.Empty;

        static FormHelper()
        {
            ScreenRectangle = Screen.PrimaryScreen.WorkingArea;
        }

        [DllImport("user32.dll")]
        public static extern IntPtr GetWindow(IntPtr hWnd, uint wWcmd);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        [DllImport("user32.dll")]
        public static extern bool IsWindowVisible(IntPtr hWnd);

        public static bool IsOverlapped(Form form)
        {
            return isoverlapped(form.Handle, form);
        }

        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 = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);

                if (winrect.Width == ScreenRectangle.Width && winrect.Y == ScreenRectangle.Height) //菜单栏。不判断遮挡(可略过)
                    return isoverlapped(preWin, form);

                if (winrect.X == 0 && winrect.Width == 54 && winrect.Height == 54) //开始按钮。不判断遮挡(可略过)
                    return isoverlapped(preWin, form);

                Rectangle formRect = new Rectangle(form.Location, form.Size); //Form窗体矩形
                if (formRect.IntersectsWith(winrect)) //判断是否遮挡
                    return true;
            }

            return isoverlapped(preWin, form);
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
}

在窗体中使用时的代码如下:

if(FormHelper.IsOverlapped(this))
{
   //具体操作,比如把窗口显示到前台
}