基于屏幕尺寸百分比计算窗口大小的简单方法

时间:2018-04-03 01:58:14

标签: c# wpf

我正在开发一个C#VSTO Excel加载项,并且有一些功能可以在单击功能区按钮后启动WPF窗口。

我有这个窗口,我将高度设置为屏幕高度的80%,宽度为屏幕宽度的60%。但是,如果用户将其DPI设置为超过100%,则此操作无效,我的WPF窗口将在其屏幕可视区域之外增长。

所以,在做了一些谷歌搜索后,我发现我必须考虑缩放因子到我的计算中。我指的是How to get Windows Display settings?来获取比例因子。

我的问题是,有更简单的方法吗?在Javascript / CSS中,我们可以使用80vh和60vw,但到目前为止,我没有在C#中看到这样有用的功能。

我觉得我必须编写代码来处理这些场景,而不是仅仅有一个代码来计算我想要的窗口大小相对于屏幕大小,这是荒谬的。

这是我现在的代码:

    var scaleFactor = GetScalingFactor();
    var handle = (IntPtr) Application.Hwnd;
    var screen = Screen.FromHandle(handle);
    var winHeight = screen.WorkingArea.Height * scaleFactor * 0.8;
    var winWidth = screen.WorkingArea.Width * scaleFactor * 0.6;

    private static float GetScalingFactor()
    {
        var g = Graphics.FromHwnd(IntPtr.Zero);
        var desktop = g.GetHdc();
        var xDpi = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSX);
        return 96 / (float) xDpi;
    }

    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
    public enum DeviceCap
    {
        VERTRES = 10,
        DESKTOPVERTRES = 117,
        /// <summary>
        /// Logical pixels inch in X
        /// </summary>
        LOGPIXELSX = 88,
        /// <summary>
        /// Logical pixels inch in Y
        /// </summary>
        LOGPIXELSY = 90

        // http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
    }

1 个答案:

答案 0 :(得分:0)

你问题的有趣部分是你希望这很简单。 您可以将设备独立像素计算为特定显示器上的乘数并应用它。

我的设置为125%,这给了我.8:

        Matrix m = PresentationSource.FromVisual(fe)
            .CompositionTarget.TransformToDevice;
        double dpiFactor = 1 / m.M11;

另一种方法是最初使窗口最大化。 渲染完成后,您知道这将大大超出显示器的大小,您可以获得窗口的实际宽度和实际高度。 然后计算* .8和* .6,大致给出你想要的尺寸。 我认为这对你的目的来说已经足够了,没有人在他们的监视器上拿这个标尺。由于窗口镀铬和最大化会产生细微差别,这会因操作系统而异。希望这是学术性的。

如果您不喜欢窗户跳跃,那么您可以将其变成动画功能。 使窗口透明,最初没有样式。 在居中的网格中显示内容。 将高度和宽度设置为您计算的大小。 然后设置窗口的大小。 不要为窗户的高度和宽度设置动画。 (它先做一个然后做另一个。)