有没有一种方法可以检查另一个程序是否正在全屏运行?

12

就像问题所说,我能否查看其他程序是否在全屏运行?

全屏表示整个屏幕被遮盖,可能在不同的视频模式下运行而不是桌面模式。


你想知道一个你可以编程控制的程序是否全屏,还是想找出另一个程序是否在全屏运行? - Justin C
2
相关:https://dev59.com/UnA65IYBdhLWcg3w-jym。还有https://dev59.com/wHA65IYBdhLWcg3wrgsa。我猜后者会回答你的问题。 - Jim Mischel
2个回答

15

这里有一段实现它的代码。你需要注意多屏幕情况,特别是在使用Powerpoint等应用程序时。

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

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

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

    public static bool IsForegroundFullScreen()
    {
        return IsForegroundFullScreen(null);
    }

    public static bool IsForegroundFullScreen(Screen screen)
    {
        if (screen == null)
        {
            screen = Screen.PrimaryScreen;
        }
        RECT rect = new RECT();
        GetWindowRect(new HandleRef(null, GetForegroundWindow()), ref rect);
        return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top).Contains(screen.Bounds); 
    }

2
如果您隐藏任务栏,则会错误地报告全屏应用程序。 - Rolle
@Rolle是正确的。有什么解决办法吗?我猜很难将在第二屏幕上运行的最大化记事本(没有任务栏)与全屏视频/游戏/PowerPoint演示文稿分开,而不考虑每个进程。 - Erlend D.
不确定你需要什么,但如果你想考虑任务栏,可以用 screen.WorkingArea 替换 screen.Bounds - Simon Mourier
1
正如@Rolle所写,如果任务栏被隐藏(在Windows 7或更早版本中的辅助屏幕上),此方法将错误地报告全屏应用程序。我只是想知道是否有任何方法可以将最大化的记事本(如果任务栏被隐藏,则您的方法将标记为全屏应用程序)与“真正”的全屏应用程序(如PowerPoint演示文稿、电影或游戏)分开。但我相当确定答案是否定的——这些应用程序之间没有技术差异,只有用户感知的差异。 - Erlend D.
@erl 一个可能的解决方案是检查前台窗口是否缺少标题栏。这是类似于 PowerPoint 幻灯片演示和记事本最大化之间唯一的真正区别。 - Cody Gray

11

我进行了一些修改。使用下面的代码时,当任务栏隐藏或在第二个屏幕上时,它不会错误地返回true。在Win 7下测试通过。

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;
    }

    [DllImport("user32.dll", SetLastError = true)]
    public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

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

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

    public static bool IsForegroundFullScreen()
    {
        return IsForegroundFullScreen(null);
    }


    public static bool IsForegroundFullScreen(System.Windows.Forms.Screen screen)
    {

        if (screen == null)
        {
            screen = System.Windows.Forms.Screen.PrimaryScreen;
        }
        RECT rect = new RECT();
        IntPtr hWnd = (IntPtr)GetForegroundWindow();


        GetWindowRect(new HandleRef(null, hWnd), ref rect);

        /* in case you want the process name:
        uint procId = 0;
        GetWindowThreadProcessId(hWnd, out procId);
        var proc = System.Diagnostics.Process.GetProcessById((int)procId);
        Console.WriteLine(proc.ProcessName);
        */


        if (screen.Bounds.Width == (rect.right - rect.left) && screen.Bounds.Height == (rect.bottom - rect.top))
        {
            Console.WriteLine("Fullscreen!")
            return true;
        }
        else {
            Console.WriteLine("Nope, :-(");
            return false;
        }


    }

3
这个方法有效的原因是屏幕大小必须完全匹配窗口,而这只适用于真正的全屏窗口。隐藏任务栏的最大化窗口仍然会有一个下拉阴影,它会增加边界超出屏幕尺寸并导致检查失败。如果禁用了下拉阴影(这是一个高级的隐藏选项),那么这种方法也会导致错误的结果。 - letmaik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接