确定打开的WPF窗口在任何监视器上是否可见 [英] Determine if an open WPF window is visible on any monitor

查看:100
本文介绍了确定打开的WPF窗口在任何监视器上是否可见的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以确定打开的WPF窗口当前在任何台式机连接的显示器中是否可见? 可见是指窗口的边界矩形与任何监视器的桌面矩形相交。

Is there a way to determine if an open WPF window is currently visible in any of the desktop's connected monitors? By visible I mean that the window's bounds rectangle intersects with the desktop rectangle of any of the monitors.

我需要此功能来确定是否需要重新放置窗口,因为监视器配置(工作区域范围,监视器计数)在应用程序重新启动之间进行了更改(这节省了窗口位置)。

I need this functionality to determine if a window needs to be repositioned because the monitor configuration (working areas bounds, monitor count) changed between restarts of my application (which saves window positions).

我想出了下面的代码,看来工作,但有几个问题:

I have come up with the code below and it seems to work, but it has several problems:


  1. 我需要引用Windows窗体。

  2. 我需要桌面的DPI设置,并将窗口形式的实际像素转换为WPF虚拟像素。

  3. 我需要一个已经存在的实际Visual实例

您知道一种解决方案可以摆脱上述3个问题中的部分或全部吗? p>

Do you know of a solution that gets rid of some or all of the 3 issues above?

using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;

internal static class Desktop
{
    private static Size dpiFactor = new Size(1.0, 1.0);
    private static bool isInitialized;

    public static IEnumerable<Rect> WorkingAreas
    {
        get
        {
            return
                Screen.AllScreens.Select(
                    screen =>
                    new Rect(
                        screen.WorkingArea.Left * dpiFactor.Width,
                        screen.WorkingArea.Top * dpiFactor.Height,
                        screen.WorkingArea.Width * dpiFactor.Width,
                        screen.WorkingArea.Height * dpiFactor.Height));
        }
    }

    public static void TryInitialize(Visual visual)
    {
        if (isInitialized)
        {
            return;
        }

        var ps = PresentationSource.FromVisual(visual);
        if (ps == null)
        {
            return;
        }

        var ct = ps.CompositionTarget;
        if (ct == null)
        {
            return;
        }

        var m = ct.TransformToDevice;
        dpiFactor = new Size(m.M11, m.M22);
        isInitialized = true;
    }
}

(初始化的)桌面类:

    private bool IsLocationValid(Rect windowRectangle)
    {
        foreach (var workingArea in Desktop.WorkingAreas)
        {
            var intersection = Rect.Intersect(windowRectangle, workingArea);
            var minVisible = new Size(10.0, 10.0);
            if (intersection.Width >= minVisible.Width && 
                intersection.Height >= minVisible.Height)
            {
                return true;
            }
        }

        return false;
    }

更新

Update

使用虚拟屏幕( SystemParameters.VirtualScreen * )不起作用,因为使用多个监视器时,桌面不是一个简单的矩形。它可能是一个多边形。虚拟屏幕中将存在盲点,因为

Using the virtual screen (SystemParameters.VirtualScreen*) does not work because when using multiple monitors the "desktop" is not a simple rectangle. It might be a polygon. There will be blind spots in the virtual screen because


  1. 连接的屏幕可以具有不同的分辨率

  2. 您可以配置每个屏幕的位置。


推荐答案

我们用于执行类似操作的代码使用来自 SystemParameters 的信息,尤其是SystemParameter.VirtualScreenLeft,顶部,宽度和高度。

The code we use to do something similar uses information from SystemParameters, in particular SystemParameter.VirtualScreenLeft, Top, Width and Height.

如果我们保存了位置和大小,则可以确定窗口是否超出了这样的范围:

If we have a saved Location and Size then we determine if the window is out of bounds like this:

bool outOfBounds =
    (location.X <= SystemParameters.VirtualScreenLeft - size.Width) ||
    (location.Y <= SystemParameters.VirtualScreenTop - size.Height) ||
    (SystemParameters.VirtualScreenLeft + 
        SystemParameters.VirtualScreenWidth <= location.X) ||
    (SystemParameters.VirtualScreenTop + 
        SystemParameters.VirtualScreenHeight <= location.Y);

这篇关于确定打开的WPF窗口在任何监视器上是否可见的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆