gpt4 book ai didi

wpf - 确定打开的 WPF 窗口是否在任何监视器上可见

转载 作者:行者123 更新时间:2023-12-04 11:56:48 26 4
gpt4 key购买 nike

有没有办法确定打开的 WPF 窗口当前是否在任何桌面连接的监视器中可见?可见是指窗口的边界矩形与任何监视器的桌面矩形相交。

我需要此功能来确定是否需要重新定位窗口,因为监视器配置(工作区域边界,监视器计数)在我的应用程序重新启动(保存窗口位置)之间发生了变化。

我想出了下面的代码,它似乎工作,但它有几个问题:

  • 我需要引用 windows 窗体。
  • 我需要桌面的 DPI 设置并将窗口窗体实际像素转换为 WPF 虚拟像素。
  • 我需要一个已经渲染的实际 Visual 实例来执行转换。

  • 您是否知道可以摆脱上述 3 个问题中的部分或全部的解决方案?
    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;
    }
    }

    (初始化的) Desktop 的用法类(class):
        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;
    }

    更新

    使用虚拟屏幕 ( SystemParameters.VirtualScreen* ) 不起作用,因为当使用多个显示器时,“桌面”不是一个简单的矩形。它可能是一个多边形。虚拟屏幕会有盲点,因为
  • 连接的屏幕可以有不同的分辨率
  • 您可以配置每个屏幕的位置。
  • 最佳答案

    我在启动时使用在我的 WPF 项目中剪断的这段代码;它是用 vb.net 编写的:

    If My.Settings.RememberWindowPositionAndSize Then
    If My.Settings.winMainWinState > 2 Then My.Settings.winMainWinState = WindowState.Normal
    If My.Settings.winMainWinState = WindowState.Minimized Then My.Settings.winMainWinState = WindowState.Normal
    Me.WindowState = My.Settings.winMainWinState
    If My.Settings.winMainWinState = WindowState.Normal Then
    Dim winBounds As New System.Drawing.Rectangle(CInt(My.Settings.winMainPosX), CInt(My.Settings.winMainPosY),
    CInt(My.Settings.winMainSizeB), CInt(My.Settings.winMainSizeH))
    For Each scr As System.Windows.Forms.Screen In System.Windows.Forms.Screen.AllScreens
    If winBounds.IntersectsWith(scr.Bounds) Then
    Me.Width = My.Settings.winMainSizeB
    Me.Height = My.Settings.winMainSizeH
    Me.Top = My.Settings.winMainPosY
    Me.Left = My.Settings.winMainPosX
    Exit For
    End If
    Next
    End If
    End If

    这是 C# 中相同的(转换后的)代码
    if (My.Settings.RememberWindowPositionAndSize) {
    if (My.Settings.winMainWinState > 2)
    My.Settings.winMainWinState = WindowState.Normal;
    if (My.Settings.winMainWinState == WindowState.Minimized)
    My.Settings.winMainWinState = WindowState.Normal;
    this.WindowState = My.Settings.winMainWinState;

    if (My.Settings.winMainWinState == WindowState.Normal) {
    System.Drawing.Rectangle winBounds = new System.Drawing.Rectangle(Convert.ToInt32(My.Settings.winMainPosX), Convert.ToInt32(My.Settings.winMainPosY), Convert.ToInt32(My.Settings.winMainSizeB), Convert.ToInt32(My.Settings.winMainSizeH));

    foreach (System.Windows.Forms.Screen scr in System.Windows.Forms.Screen.AllScreens) {
    if (winBounds.IntersectsWith(scr.Bounds)) {
    this.Width = My.Settings.winMainSizeB;
    this.Height = My.Settings.winMainSizeH;
    this.Top = My.Settings.winMainPosY;
    this.Left = My.Settings.winMainPosX;
    break;
    }
    }
    }
    }

    关于wpf - 确定打开的 WPF 窗口是否在任何监视器上可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10434338/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com