WPF Window title bar different size with PerMonitorV2 or PerMonitor

132 Views Asked by At

I have a wpf application (.Net 7) with DPI Awareness but I have some problems with the sizes of windows title bar with different DPI scale in different pc's.

I two pc's has Windows 11 version 22H2. The pc 1 (desktop) with two monitors of 1920x1080 with 100% of scale. The pc 2 (laptop) one monitor of 2880x1800 with 175% of scale and the other with 1920x1080 with 100% of scale.

This is how the windows looks normally:

enter image description here

This is my manifest field:

 <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
        <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
        <!--<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>-->
        <longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
    </windowsSettings>
  </application>

The problem is in the pc 1 works fine with PerMonitor but not with PerMonitorV2. And the pc 2 works fine with PerMonitorV2 but not with PerMonitor.

Here are the example: PC 1 with PerMonitorV2 and the monitor with a scale of 175% (using PerMonitor works well in every monitor with every scale):

enter image description here

PC 2 with PerMonitor and the monitor in one with 2880x1800 with 175% of scale and the other with 1920x1080 with 100% of scale (using PerMonitorV2 works well in every monitor with every scale):

Initially the app in monitor 1 (primary screen):

enter image description here

And move it to monitor 2:

enter image description here

Initially the app in monitor 2 (principaly screen):

enter image description here

And move it to monitor 1:

enter image description here

And this is my code OnDpiChanged:

Protected Overrides Sub OnDpiChanged(oldValueDpi As DpiScale, newDpi As DpiScale)
    Dim dpi = VisualTreeHelper.GetDpi(Me).PixelsPerDip
    Dim screen As Forms.Screen = Forms.Screen.FromHandle(New WindowInteropHelper(Me).Handle)
    If screen.Bounds.Width > screen.Bounds.Height Then
        Me.Scrll.LayoutTransform = New ScaleTransform(1 / dpi * screen.Bounds.Width / 1920, 1 / dpi * screen.Bounds.Height / 1080)
    Else    'in case the monitor is vertical
        Me.Scrll.LayoutTransform = New ScaleTransform(1 / dpi, 1 / dpi)
    End If
End Sub
1

There are 1 best solutions below

0
emoacht On

Window title bar is called as non-client area and one of differences between PerMonitor(V1) and PerMonitorV2 is the support for automatic scaling of non-client area. PerMonitorV2 supercedes PerMonitor(V1) and once you specify PerMonitorV2, you won't need to set the scaling on your own at all except you have a element which requires a special care.

In conclusion, I recommend to specify PerMonitorV2 and remove your logic to manually set the scaling.