By Boris


2012-11-05 08:08:57 8 Comments

I've created a simple Winforms application in C#. When I run the application on a machine with high DPI settings (e.g. 150%), the application gets scaled up. So far so good! But instead of rendering the fonts with a higher font size, all texts are just scaled up, too. That of course leads to very blurry text (on all controls like buttons etc.).

Shouldn't windows take care of rendering the texts correctly? For example my application's title bar is rendered crisp & clear.

5 comments

@Aranxo 2019-10-21 00:22:49

Since at least Visual Studio 2017 you just have to add a manifest file and uncomment this section:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
        <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
</application>

@Wollmich 2018-08-13 08:10:45

Using .NET Framework 4.7 and Windows 10 Creators Update or newer you must do the following things to configure high DPI support for your Windows Form application:

Declare compatibility with Windows 10.

To do this, add the following to your manifest file:

<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
  <application>
    <!-- Windows 10 compatibility -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
  </application>
</compatibility>

Enable per-monitor DPI awareness in the app.config file.

Windows Forms introduces a new System.Windows.Forms.ApplicationConfigurationSection element to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.

<System.Windows.Forms.ApplicationConfigurationSection>
  <add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>

Important

In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no longer recommended, since it overrides settings defined on the app.config file.

Call the static EnableVisualStyles method.

This should be the first method call in your application entry point. For example:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form2());   
}

The advantage of this is the support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows Forms application has been launched.

Source: High DPI support in Windows Forms

@Vasco Bonilla 2018-03-06 18:48:16

None of these suggestions worked for me but, something happened after I removed the Form.Font = new ... from the Form.Design.cs, the form started to re-scale properly, it works if the Font is defined in the constructor or not at all. Why? somebody else may be able to explained, I just can talk about the changed I made and took me a few minutes to figured out it was the root cause for the form I was working on. Hope it helps.

@Hans Passant 2012-11-05 08:37:17

Once you go past 100% (or 125% with the "XP-style DPI scaling" checkbox ticked), Windows by default takes over the scaling of your UI. It does so by having your app render its output to a bitmap and drawing that bitmap to the screen. The rescaling of that bitmap makes the text inevitably look fuzzy. A feature called "DPI virtualization", it keeps old programs usable on high resolution monitors.

You have to explicitly let it know that you can handle higher DPI settings by adding the <dpiAware> element to your manifest. The MSDN page is here but it isn't complete since it is omitting the UAC settings. Project + Add New Item, pick "Application Manifest File". Edit the manifest text or copy/paste this:

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
    <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
    <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
</assembly>

You can also pinvoke SetProcessDPIAware() in your Main() method, necessary for example if you deploy with ClickOnce:

    [STAThread]
    static void Main() {
        if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());             // Edit as needed
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();

UPDATE, this common need is finally a bit easier if you use VS2015 Update 1 or higher. The added manifest already has the relevant directive, just remove the comments.


Keyword for search so I can find this post back: dpiAware

@Boris 2012-11-05 08:53:55

Thanks, your solution works fine. The only problem left is that all images are now at their original sizes. I guess I'll have to find a way to add additional "retina"-icons to my GUI...

@gajo357 2014-05-30 13:03:46

@HansPassant I have the same problem with blurry fonts, and after applying this solution, my controls don't scale and they can't fit. How to get both to work?

@Jason Williams 2014-08-27 22:20:02

For anyone investigating this Win8 madness, SetProcessDPIAware is deprecated, and it also doesn't work properly (at least not in Win8.1), causing unpredictable scaling on different controls. I strongly recommend using the manifest approach instead.

@Hans Passant 2014-08-27 22:26:34

Hmya, Windows 8.1 acquired per-monitor DPI. I wasn't aware that I needed that.

@Matías 2015-03-17 13:10:34

If you are going to use ClickOnce for deployment, you cannot use the dpiAware option in manifest, use SetProcessDPIAware() instead.

@jww 2018-09-26 02:23:05

Excellent answer. I can't help but wonder how long it took you to piece it together.

@Profesor08 2019-01-09 12:42:25

Best solution, it solved all my problems (wrong resolution detection and blurry fonts) in 2 lines of code.

@shanthi_karthika 2014-12-04 05:58:40

Applications can be developed in two different mode.

The first one is to declare our application to be non-DPI-aware (not declaring anything will default to this). In this case the operating system will render our application under the expected 96 DPI and then will do to the bitmap scaling that we discussed before. The result will be a blurry looking application, but with a correct layout.

The second option is to declare the application as DPI-aware. In this case the OS will not do any scaling and will let your application render according to the original DPI of the screen. In case of a per-monitor-DPI environment, your application will be rendered with the highest DPI of all the screens, then this bitmap will be scaled down to the proper size for each monitor. Downscaling results in a better viewing experience than upscaling but you might still notice some fuzziness.

If you want to avoid that, you must declare your application as per-monitor-DPI-aware. Then you must detect when your application is dragged across different monitors and render according to the DPI of the current one.

Declaring the DPI awareness is done in a manifest file.

refer the following link stackoverflow

@Cee McSharpface - it 2018-10-11 10:42:41

what if users have a window in restored size and move it so parts of it are on different monitors? do we need to render everything twice and use the monitor boundaries as bounding boxes? how much of that is covered by the winforms libraries?

Related Questions

Sponsored Content

3 Answered Questions

[SOLVED] Mixed WPF and winforms project DPI awareness

0 Answered Questions

WPF application "bitmap-scaled" on Remote Desktop with Hi DPI

  • 2018-02-15 22:12:31
  • Michal.Jan008
  • 315 View
  • 1 Score
  • 0 Answer
  • Tags:   c# wpf rdp dpi-aware

1 Answered Questions

5 Answered Questions

[SOLVED] Adjust RichTextBox font size under High DPI setting

8 Answered Questions

[SOLVED] AutoScaleMode problems with changed default font

  • 2010-06-04 10:12:43
  • Doc Brown
  • 93315 View
  • 35 Score
  • 8 Answer
  • Tags:   c# .net winforms

1 Answered Questions

[SOLVED] SetProcessDPIAware in VSTO add-in

1 Answered Questions

2 Answered Questions

[SOLVED] Problems getting WinForms to scale correctly with DPI

1 Answered Questions

Sponsored Content