简体   繁体   English

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

[英]How to check whether application is running fullscreen mode on any screen?

I'd like to check, if any screen hosts application in fullscreen mode. 我想检查一下,是否有任何屏幕以全屏模式托管应用程序。 I have solution only for one screen which is code copied from here: [WPF] [C#] How-to : Detect if another application is running in full screen mode. 我仅对从此处复制代码的一个屏幕有解决方案: [WPF] [C#]如何:检测另一个应用程序是否在全屏模式下运行。 This solution is based on 该解决方案基于

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

which gathers only active window handle. 仅收集活动窗口句柄。 The problem is, I have two screens. 问题是,我有两个屏幕。 I've searched many sites but none of them answers my question. 我搜索了许多站点,但是没有一个站点回答我的问题。 It is not about capturing screenshot, which is simple and doesn't rely on P/Invoke. 这与捕获屏幕快照无关,这很简单,并且不依赖于P / Invoke。

Is this possible? 这可能吗?

No ready-to-use solution here, but let's see.. 这里没有现成的解决方案,但让我们看看。

Get list of all displayed windows and check positions and sizes of those windows - possible, lots of tools does it, many articles on that, I'll skip this one. 获取所有显示的窗口的列表,并检查这些窗口的位置和大小-可能,有很多工具可以做到这一点,关于这方面的文章很多,我将跳过这一部分。 Then, you can call MonitorFromWindow for each or some windows and compare window dimensions&position against monitor info. 然后,您可以为每个或某些窗口调用MonitorFromWindow ,并将窗口的尺寸和位置与监视器信息进行比较。 If windowpos ~= 0,0 and windowsize ~= monitorresolution you could assume that this window is in fullscreen mode. 如果windowpos〜= 0,0和windowsize〜= monitorresolution,则可以假定此窗口处于全屏模式。

On the other hand, if already having a list of all HWNDs, then why not just Query the window for its placement and check the WINDOWPLACEMENT.showCmd for SW_MAXIMIZE/SW_SHOWMAXIMIZED flags. 另一方面,如果已经具有所有HWND的列表,那么为什么不只查询窗口的位置并检查WINDOWPLACEMENT.showCmd中的SW_MAXIMIZE / SW_SHOWMAXIMIZED标志。 That won't tell you which monitor is it, but should tell you at least if the window is maximized and if it's enough for you.. 那不会告诉您它是哪个监视器,但是至少应该告诉您窗口是否已最大化以及是否足以容纳您。

I don't know how fast/slow would it be to do it like that, but, yes, it seems possible. 我不知道这样做会有多快/慢,但是,是的,这似乎是可能的。

You could use EnumWindows in conjunction with Screen.FromHandle . 您可以将EnumWindowsScreen.FromHandle结合使用。 And maybe GetWindowRect() for calculations. 也许可以使用GetWindowRect()进行计算。

Something like (pseudo-code!): 类似于(伪代码!):

//------------------------------
//this sample code is taken from http://pinvoke.net/default.aspx/user32/EnumWindows.html

public delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumWindows(EnumedWindow lpEnumFunc, ArrayList lParam);

public static ArrayList GetWindows()
{    
    ArrayList windowHandles = new ArrayList();
    EnumedWindow callBackPtr = GetWindowHandle;
    EnumWindows(callBackPtr, windowHandles);
    return windowHandles;     
}

private static bool GetWindowHandle(IntPtr windowHandle, ArrayList windowHandles)
{
    windowHandles.Add(windowHandle);
    return true;
}

//------------------------------

[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, [In,Out] ref Rect rect);

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

static void Main() {
    foreach(IntPtr handle in GetWindows())
    {
      Screen scr = Screen.FromHandle(handle);

      if(IsFullscreen(handle, scr))
      {
          // the window is fullscreen...
      }
    }
}

private bool IsFullscreen(IntPtr wndHandle, Screen screen)
{
    Rect r = new Rect();
    GetWindowRect(wndHandle, ref r);
    return new Rectangle(r.Left, r.Top, r.Right-r.Left, r.Bottom-r.Top)
                          .Contains(screen.Bounds);
}

I wrote piece of code which is working : 我写了一段有效的代码

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);
}

} }

Thanks for @SamAxe and @quetzalcoatl for providing me useful tips. 感谢@SamAxe和@quetzalcoatl为我提供有用的提示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 检查应用程序是否正在运行? - Check whether an application is running? 有什么方法可以检测外部进程是否在独占全屏模式下运行? - Is there any way to detect if an external process is running on exclusive fullscreen mode? 如何检查.NET应用程序是否在终端服务器上运行? - How can I check whether my .NET application is running on a Terminal Server? 如何检查用户是否有任何角色? - How to check whether user has any role? 如何在 ASP.NET CORE 2.1 中的 Program.cs 文件中检查代码是在开发模式还是生产模式下运行? - How to check whether the code is running in development or Production mode in Program.cs file in ASP.NET CORE 2.1? 检查应用程序是否在终端服务下而不是远程桌面下运行 - Check whether application is running under Terminal Services as opposed to Remote Desktop 如何确定Web应用程序当前是否正在运行 - How to determine whether a web application is currently running 检查winform是否隐藏在以独占全屏模式运行的游戏后面 - check if winform is hidden behind a game running in exclusive full screen mode 如何在C#内部检测应用程序是在控制台还是Windows模式 - How to detect internally whether the application is in console or windows mode in C# 如何检查我的远程计算机是否正在运行并且可以访问? - How to check whether my remote machine is running and i have access?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM