Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems getting WinForms to scale correctly with DPI

I'm running into problems with getting a WinForms app to display correctly at high DPI settings. I've checked various web sites, and the WinForms all have the correct AutoScaleMode. I've tried setting this to both DPI and Font. However, the forms always get cut off near the bottom when using high DPI settings (e.g. 125%).

I added some code to check, and if I set AutoScaleMode to DPI, when the form loads, I see that AutoScaleDimensions is 120,120 when the form loads, and CurrentAutoScaleDimensions is also 120,120. In the Form.designer.cs file, there is a line to set AutoScaleDimension to 96,96.

If I set AutoScaleMode to Font, then I can see in designer that AutoScaleDimension is correctly set to new System.Drawing.SizeF(6F, 13F), but when the form loads, both AutoScaleDimension and CurrentAutoScaleDimension are set to 8F,16F.

This app mixes some WPF with WinForms, and the WPF screens appear first. So based on DPI Scaling in .Net 3.5 in Mixed WinForms and WPF Application I tried setting the TextFormattingMode for the application, and for the WPF screens that show first, to "Display", but it makes no difference.

I am, frankly, at a loss as to what's causing this. I suppose I could add code to resize things programmatically by detecting the DPI at runtime, but I shouldn't have to do that. The AutoScaleMode (and related) properties are supposed to make this fairly automatic. So what else should I be checking for that might cause this problem?

like image 838
WarnerYoung Avatar asked Jun 16 '14 21:06

WarnerYoung


1 Answers

I had a similar problem just a few days ago. After a couple of hours research, I finally found a very simple solution -- adding <dpiAware> to the application manifest. Here is an example from Microsoft's website.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>True</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>

For my case, I need to set the <dpiAware> to Per-monitor to make it work normally. That is, change the line in the middle to <dpiAware>Per-monitor</dpiAware>.

The differences between each value are listed below(These are from MSDN):

  • False -- Sets the application to not DPI-aware.
  • True -- Sets the application to system DPI–aware.
  • Per-monitor -- On Windows 8.1, sets the application to per monitor-DPI aware. On Windows Vista through Windows 8, sets the application to not DPI–aware.
  • True/PM -- On Windows 8.1, sets the application to per monitor-DPI aware. On Windows Vista through Windows 8, sets the application to system-DPI aware.
like image 169
Anthony Huang Avatar answered Nov 15 '22 21:11

Anthony Huang