Почему 1920 устройств-независимых единиц не 1920 пикселей с 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>

по данным этой сообщение в блоге msdn:

1 устройства независимой пиксел = 1/96 дюйма.
1 физический пиксель = 1 / DPI (зависит от системного DPI)

настройки системы по умолчанию обычно выбирают DPI 96, поэтому эти два типа пиксели получаются одинакового размера.

однако это, похоже, не так, так как мой Window явно меньше 1920 пикселей в ширину.
Если я максимизирую Window и проверьте его ActualWidth кажется 1936.

почему это произошло?

3 ответов


вопрос больше по строкам:

почему окна.ActualWidth сообщает ширину, которая не кажется "реальной" шириной окна?

ответ в том, что выглядит так: полная ширина окна не совсем полное ширина.

при установке Width, запрос ActualWidth и GetWindowRect чтобы получить "нет-ложь, что windows думает, что моя ширина", вы устанавливаете или получение ширины окна, включая невидимые части.

эти невидимые части, особенно на Windows 10, включает в себя немного дополнительного пространства для облегчения пользователям изменять размер окна, даже если они немного от границы:

resize off of the window

(обратите внимание, что моя мышь находится не на границе, а немного справа)

это означает, что при максимизации окна ваша ширина все еще "мягкий" с этим невидимым пространством, и, таким образом, ваш размер окна будет больше, чем размер экрана.

как вы можете получить ширину дополнительного пространства? GetSystemMetrics С SM_CXSIZEFRAME и SM_CXPADDEDBORDER ваш друг здесь (пример включает код из pinvoke.net):

int extraBorderStuff = GetSystemMetrics(SystemMetric.SM_CXSIZEFRAME)
                       + GetSystemMetrics(SystemMetric.SM_CXPADDEDBORDER);
double realWidthForSure = ActualWidth - borderSize * 2;

если вы затем развернуть окно, вы должны заметить, что realWidthForSure должен равняться вашему 1920px, который вы ожидаете.


окно действительно имеет ширину 1936 пикселей!

когда окно развернуто, граница вокруг него обрезается. Хотя он больше не виден, он по-прежнему считается частью окна. В теме Aero эта граница имеет ширину 8px с каждой стороны, следовательно, 16px дополнительно:

Window chrome in Aero theme

Если вы переключитесь на классическую тему, это только 4px с каждой стороны, поэтому ваше окно будет 1928 пикселей в ширину.


каковы ваши спецификации экрана? например, мой монитор имеет шаг = 0.282 мм; что равно 90.0709... ИЦП. Окно шириной 1920 пикселей будет иметь фактическую ширину 2,046 единиц в WPF.

определите DPI вашего экрана (25.4 / pitch, если у вас есть шаг в мм)

96 / DPI * 1920 = > фактическая ширина