C# 如何检查应用程序是否在任何屏幕上运行全屏模式?

C# 如何检查应用程序是否在任何屏幕上运行全屏模式?,c#,pinvoke,user32,C#,Pinvoke,User32,我想检查一下,是否有任何屏幕主机应用程序处于全屏模式。我只有一个屏幕的解决方案,它是从这里复制的代码:这个解决方案基于 [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); 它只收集活动的窗口句柄。问题是,我有两个屏幕。我搜索了很多网站,但没有一个能回答我的问题。它不是关于截图,截图很简单,不依赖于P/Invoke 这可能吗?这里没有现成的解决方案,但让我们看看 获取所有显示窗口的列表,并检查

我想检查一下,是否有任何屏幕主机应用程序处于全屏模式。我只有一个屏幕的解决方案,它是从这里复制的代码:这个解决方案基于

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
它只收集活动的窗口句柄。问题是,我有两个屏幕。我搜索了很多网站,但没有一个能回答我的问题。它不是关于截图,截图很简单,不依赖于P/Invoke


这可能吗?

这里没有现成的解决方案,但让我们看看

获取所有显示窗口的列表,并检查这些窗口的位置和大小-可能,有很多工具可以做到这一点,很多关于这方面的文章,我将跳过这一篇。然后,您可以调用每个或一些窗口,并将窗口尺寸和位置与监视器信息进行比较。如果windowpos~=0,0和WindowsSize~=monitorresolution,则可以假定此窗口处于全屏模式

另一方面,如果已经有一个所有HWD的列表,那么为什么不直接检查
WINDOWPLACEMENT.showCmd
中的SW_MAXIMIZE/SW_showmized标志。这不会告诉你它是哪个监视器,但至少应该告诉你窗口是否最大化,是否足够

我不知道这样做有多快/慢,但是,是的,这似乎是可能的

您可以与一起使用。也许是为了计算

类似(伪代码!):


我写了一段正在运行的代码:

namespace EnumWnd
{
using System;
using System.Runtime.InteropServices;
using System.Text;

[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
    public int Left;

    public int Top;

    public int Right;

    public int Bottom;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct MonitorInfoEx
{
    public int cbSize;
    public Rect rcMonitor;
    public Rect rcWork;
    public UInt32 dwFlags;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szDeviceName;
}

internal class Program
{
    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hWnd, out Rect lpRect);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    protected static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll")]
    protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

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

    [DllImport("User32")]
    public static extern IntPtr MonitorFromWindow(IntPtr hWnd, int dwFlags);

    [DllImport("user32", EntryPoint = "GetMonitorInfo", CharSet = CharSet.Auto,
        SetLastError = true)]
    internal static extern bool GetMonitorInfoEx(IntPtr hMonitor, ref MonitorInfoEx lpmi);

    protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
    {
        const int MONITOR_DEFAULTTOPRIMARY = 1;
        var mi = new MonitorInfoEx();
        mi.cbSize = Marshal.SizeOf(mi);
        GetMonitorInfoEx(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), ref mi);

        Rect appBounds;
        GetWindowRect(hWnd, out appBounds);
        int size = GetWindowTextLength(hWnd);
        if (size++ > 0 && IsWindowVisible(hWnd))
        {
            var sb = new StringBuilder(size);
            GetWindowText(hWnd, sb, size);

            if (sb.Length > 20)
            {
                sb.Remove(20, sb.Length - 20);
            }

            int windowHeight = appBounds.Right - appBounds.Left;
            int windowWidth = appBounds.Bottom - appBounds.Top;

            int monitorHeight = mi.rcMonitor.Right - mi.rcMonitor.Left;
            int monitorWidth = mi.rcMonitor.Bottom - mi.rcMonitor.Top;

            bool fullScreen = (windowHeight == monitorHeight) && (windowWidth == monitorWidth);

            sb.AppendFormat(" Wnd:({0} | {1}) Mtr:({2} | {3} | Name: {4}) - {5}", windowWidth, windowHeight, monitorWidth, monitorHeight, mi.szDeviceName, fullScreen);

            Console.WriteLine(sb.ToString());
        }
        return true;
    }

    private static void Main()
    {
        while (true)
        {
            EnumWindows(EnumTheWindows, IntPtr.Zero);
            Console.ReadKey();
            Console.Clear();
        }
    }

    protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
}
}


感谢@SamAxe和@quetzalcatl为我提供了有用的提示。

GetForgroundWindow
只提供了一个窗口句柄(hWnd)。使用任何你喜欢的枚举窗口的方法——它们都会给你一个hWnd——并插入这些值,而不是前台的hWnd。试试这个:通过使用绑定,你可以存储变量来检查sceen是否正确maximized@PieterSchool-这与WPF无关,但是谢谢你的时间:)@Fka我是因为这个链接才这么想的sorry@Fka:想象一张纸。绘制两个大小不同的矩形,每个矩形共享一个边框。由于没有更好的术语,这篇论文代表了你的虚拟桌面。矩形代表您的监视器
GetWindowRect
屏幕。边界在虚拟桌面坐标中给出。没有必要为显示器的分辨率而烦恼。
namespace EnumWnd
{
using System;
using System.Runtime.InteropServices;
using System.Text;

[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
    public int Left;

    public int Top;

    public int Right;

    public int Bottom;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct MonitorInfoEx
{
    public int cbSize;
    public Rect rcMonitor;
    public Rect rcWork;
    public UInt32 dwFlags;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szDeviceName;
}

internal class Program
{
    [DllImport("user32.dll")]
    public static extern bool GetWindowRect(IntPtr hWnd, out Rect lpRect);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    protected static extern int GetWindowTextLength(IntPtr hWnd);

    [DllImport("user32.dll")]
    protected static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);

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

    [DllImport("User32")]
    public static extern IntPtr MonitorFromWindow(IntPtr hWnd, int dwFlags);

    [DllImport("user32", EntryPoint = "GetMonitorInfo", CharSet = CharSet.Auto,
        SetLastError = true)]
    internal static extern bool GetMonitorInfoEx(IntPtr hMonitor, ref MonitorInfoEx lpmi);

    protected static bool EnumTheWindows(IntPtr hWnd, IntPtr lParam)
    {
        const int MONITOR_DEFAULTTOPRIMARY = 1;
        var mi = new MonitorInfoEx();
        mi.cbSize = Marshal.SizeOf(mi);
        GetMonitorInfoEx(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), ref mi);

        Rect appBounds;
        GetWindowRect(hWnd, out appBounds);
        int size = GetWindowTextLength(hWnd);
        if (size++ > 0 && IsWindowVisible(hWnd))
        {
            var sb = new StringBuilder(size);
            GetWindowText(hWnd, sb, size);

            if (sb.Length > 20)
            {
                sb.Remove(20, sb.Length - 20);
            }

            int windowHeight = appBounds.Right - appBounds.Left;
            int windowWidth = appBounds.Bottom - appBounds.Top;

            int monitorHeight = mi.rcMonitor.Right - mi.rcMonitor.Left;
            int monitorWidth = mi.rcMonitor.Bottom - mi.rcMonitor.Top;

            bool fullScreen = (windowHeight == monitorHeight) && (windowWidth == monitorWidth);

            sb.AppendFormat(" Wnd:({0} | {1}) Mtr:({2} | {3} | Name: {4}) - {5}", windowWidth, windowHeight, monitorWidth, monitorHeight, mi.szDeviceName, fullScreen);

            Console.WriteLine(sb.ToString());
        }
        return true;
    }

    private static void Main()
    {
        while (true)
        {
            EnumWindows(EnumTheWindows, IntPtr.Zero);
            Console.ReadKey();
            Console.Clear();
        }
    }

    protected delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
}