Why are 1920 devices independent devices not 1920 pixels with 96 DPI?

My Windows settings are set to DPI 96. However, when I create the following Window , it will be slightly smaller than my screen (which is set to 1920 * 1080 resolution):

 <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> 

According to this msdn blog post:

1 device independent pixel = 1/96 inch.
1 physical pixel = 1 / DPI (depending on system DPI)

The default system settings usually choose DPI 96, so these two types of pixels are the same size.

However, this does not seem to be the case, since my Window clearly smaller than 1920 pixels wide.
If I maximize Window and ActualWidth its ActualWidth , it will be 1936 .

Why is this so?

+7
dpi screen-resolution wpf
source share
3 answers

The question is more line by line:

Why is Window.ActualWidth reporting a width that is not the "real" window width?

The answer is that what looks like the full width of the window does not match the full width.

When you set Width , query ActualWidth or even use GetWindowRect to get "no lies that think of my window width", you set or get the window width including the invisible parts.

These invisible parts, especially in Windows 10, contain a little extra space, allowing users to easily resize the window, even if they are slightly different from the border:

resize window

(note that my mouse is not on the border, but a little to the right)

This means that when you maximize your window, your width is still "padded" with this invisible space, and therefore your window will be larger than your screen.

How can you get the width of the extra 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; 

If you then enlarge your window, you should notice that realWidthForSure should equal your 1920px, which you expect.

+3
source share

The window really has a width of 1936 pixels!

When the window is maximized, the border around it is cropped. Although it is no longer visible, it is still considered part of the window. In the Aero test, this border has a width of 8 pixels on each side, so an additional 16px:

Chrome window in Aero theme

If you switch to the Classic theme, it will be only 4 pixels on each side, so your window will be 1928 pixels wide.

+3
source share

What are your screen specifications? eg. my monitor has a pitch = 0.282 mm; which is 90.0709 ... ppi. A window with a width of 1920 pixels will have an actual width of 2046 units in WPF.

define your DPI screen (25.4 / pitch if you have a pitch in mm)

96 / DPI * 1920 => Actual width

-one
source share

All Articles