为什么1920设备无关单元不是1920像素,96 DPI?

Tim*_*ann 7 wpf dpi screen-resolution

我的Windows设置被设置为DPI为96.但是,当我创建以下内容时Window,它将比我的屏幕(设置为1920*1080分辨率)小一点:

<Window x:Class="WPF_Sandbox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_Sandbox"
        mc:Ignorable="d"
        Title="MainWindow"
        Width="1920">
</Window>
Run Code Online (Sandbox Code Playgroud)

根据这篇 msdn博客文章:

1个设备独立像素= 1/96英寸.
1个物理像素= 1/DPI(取决于系统DPI)

默认系统设置通常选择DPI为96,因此这两种像素的大小相同.

然而,这似乎并非如此,因为我Window显然不到1920像素宽.
如果我最大化Window并检查ActualWidth它似乎是1936.

为什么会这样?

Fri*_*Guy 5

问题更多的是:

为什么Window.ActualWidth报告的宽度似乎不是Window的“实际”宽度?

答案是看起来像窗口的整个宽度并不完全是整个宽度。

设置Width,查询ActualWidth甚至使用GetWindowRect来获取“无赖窗口认为我的宽度是多少”时,您就是在设置或获取包括不可见部分在内的窗口的宽度。

这些不可见的部分,尤其是在Windows 10上,包括一些额外的空间,即使用户离边界有点距离,也可以使用户轻松调整窗口的大小:

调整窗口大小

(请注意,我的鼠标不在边框上,而是稍微偏右)

这意味着,当您最大化窗口时,您的宽度仍被该不可见空间“填充”,因此窗口大小将大于屏幕大小。

如何获取多余空间的宽度?GetSystemMetricsSM_CXSIZEFRAMESM_CXPADDEDBORDER是您的朋友(示例包括来自pinvoke.net的代码):

int extraBorderStuff = GetSystemMetrics(SystemMetric.SM_CXSIZEFRAME)
                       + GetSystemMetrics(SystemMetric.SM_CXPADDEDBORDER);
double realWidthForSure = ActualWidth - borderSize * 2;
Run Code Online (Sandbox Code Playgroud)

如果您随后将窗口最大化,则应注意该值realWidthForSure应等于您期望的1920像素。