Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure an app to run correctly on a machine with a high DPI setting (e.g. 150%)?

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.

like image 625
Boris Avatar asked Nov 05 '12 08:11

Boris


People also ask

How do I fix the DPI of an app?

Select Display > Change the size of text, apps, and other items, and then adjust the slider for each monitor. Right-click the application, select Properties, select the Compatibility tab, and then select the Disable display scaling on high DPI settings check box.

What is high DPI settings?

High DPI displays have increased pixel density, compared to standard DPI displays. Pixel density is measured in Dots per Inch (DPI) or Pixels per Inch (PPI), and is determined by the number of display pixels and their size.

What does enable high DPI Scaling do?

High-DPI scaling improvements on Windows 10 For this and other similar situations, Windows 10 now includes an option to force a particular app to run as a DPI-unware process. The new option is called "System (Enhanced)," and when enabled the text and interface will look crispier and elements will be sized correctly.


2 Answers

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

like image 104
Hans Passant Avatar answered Sep 17 '22 16:09

Hans Passant


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

like image 38
shanthi_karthika Avatar answered Sep 17 '22 16:09

shanthi_karthika