为什么 1920 设备独立单位不是 1920 像素和 96 DPI?
Why is 1920 device-independent units not 1920 pixel with 96 DPI?
我的 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>
根据 this msdn 博客 post:
1 device independent pixel = 1/96 inch.
1 physical pixel = 1/DPI (dependent on the system DPI)
Default system settings usually choose a DPI of 96 so these two types of pixels come out to be the same size.
然而,情况似乎并非如此,因为我的 Window
明显小于 1920 像素宽。
如果我最大化 Window
并检查它的 ActualWidth
它似乎是 1936
.
为什么会这样?
您的屏幕规格是多少?例如我的显示器间距 = 0.282 毫米;等于 90.0709...ppi。 1920 像素宽 window 在 WPF 中的实际宽度为 2,046 个单位。
确定屏幕的 DPI(如果间距以毫米为单位,则为 25.4/间距)
96/DPI * 1920 => 实际宽度
window确实有1936像素的宽度!
当 window 最大化时,它周围的边框会被裁剪。尽管它不再可见,但仍被视为 window 的一部分。在 Aero 主题中,此边框每边的宽度均为 8px,因此额外增加了 16px:
如果您切换到经典主题,每边只有 4 像素,所以您的 window 将是 1928 像素宽。
问题大致如下:
Why does Window.ActualWidth report a width that does not appear to be the 'real' width of the Window?
答案是 看起来像 window 的全宽并不完全是 全 的宽度。
当您设置 Width
、查询 ActualWidth
,甚至使用 GetWindowRect
获取 "no-lies what does windows think my width is" 时,您正在设置或获取Window 包括 不可见部分。
那些不可见的部分,尤其是在 Windows 10 上,包括一些额外的 space 以方便用户调整 window 的大小,即使它们有点小有点偏离边界:
(请注意,我的鼠标不在边框上,而是偏右了一点)
这意味着当你最大化你的 window 时,你的宽度仍然是 "padded" 而那个不可见的 space,因此你的 window 大小会比你的大屏幕尺寸。
如何检索额外 space 的宽度? GetSystemMetrics
with SM_CXSIZEFRAME
and SM_CXPADDEDBORDER
is your friend here (example includes code from pinvoke.net):
int extraBorderStuff = GetSystemMetrics(SystemMetric.SM_CXSIZEFRAME)
+ GetSystemMetrics(SystemMetric.SM_CXPADDEDBORDER);
double realWidthForSure = ActualWidth - borderSize * 2;
如果您随后最大化 window,您应该注意到 realWidthForSure
应该等于您期望的 1920px。
我的 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>
根据 this msdn 博客 post:
1 device independent pixel = 1/96 inch.
1 physical pixel = 1/DPI (dependent on the system DPI)Default system settings usually choose a DPI of 96 so these two types of pixels come out to be the same size.
然而,情况似乎并非如此,因为我的 Window
明显小于 1920 像素宽。
如果我最大化 Window
并检查它的 ActualWidth
它似乎是 1936
.
为什么会这样?
您的屏幕规格是多少?例如我的显示器间距 = 0.282 毫米;等于 90.0709...ppi。 1920 像素宽 window 在 WPF 中的实际宽度为 2,046 个单位。
确定屏幕的 DPI(如果间距以毫米为单位,则为 25.4/间距)
96/DPI * 1920 => 实际宽度
window确实有1936像素的宽度!
当 window 最大化时,它周围的边框会被裁剪。尽管它不再可见,但仍被视为 window 的一部分。在 Aero 主题中,此边框每边的宽度均为 8px,因此额外增加了 16px:
如果您切换到经典主题,每边只有 4 像素,所以您的 window 将是 1928 像素宽。
问题大致如下:
Why does Window.ActualWidth report a width that does not appear to be the 'real' width of the Window?
答案是 看起来像 window 的全宽并不完全是 全 的宽度。
当您设置 Width
、查询 ActualWidth
,甚至使用 GetWindowRect
获取 "no-lies what does windows think my width is" 时,您正在设置或获取Window 包括 不可见部分。
那些不可见的部分,尤其是在 Windows 10 上,包括一些额外的 space 以方便用户调整 window 的大小,即使它们有点小有点偏离边界:
(请注意,我的鼠标不在边框上,而是偏右了一点)
这意味着当你最大化你的 window 时,你的宽度仍然是 "padded" 而那个不可见的 space,因此你的 window 大小会比你的大屏幕尺寸。
如何检索额外 space 的宽度? GetSystemMetrics
with SM_CXSIZEFRAME
and SM_CXPADDEDBORDER
is your friend here (example includes code from pinvoke.net):
int extraBorderStuff = GetSystemMetrics(SystemMetric.SM_CXSIZEFRAME)
+ GetSystemMetrics(SystemMetric.SM_CXPADDEDBORDER);
double realWidthForSure = ActualWidth - borderSize * 2;
如果您随后最大化 window,您应该注意到 realWidthForSure
应该等于您期望的 1920px。