How to get the correct DPI?

0

I'm trying to get DPI from the monitor, but it always returns 96, I've researched and found a lot of people with the same problem.

float dx, dy;

         Graphics g = this.CreateGraphics();
         try
         {
             dx = g.DpiX;
             dy = g.DpiY;
         }
         finally
         {
             g.Dispose();
         }


         MessageBox.Show($"{dx} | {dy}");
    
asked by anonymous 14.08.2017 / 06:35

1 answer

1

Try to work around WinAPI. First, you'll need to add these references:

using System.Drawing;
using System.Windows.Forms;

You can get DPI from all installed monitors with GetDpiForMonitor calls:

public static class ScreenExtensions
{
    public static void GetDpi(this System.Windows.Forms.Screen screen, DpiType dpiType, out uint dpiX, out uint dpiY)
    {
        var pnt = new System.Drawing.Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1);
        var mon = MonitorFromPoint(pnt, 2/*MONITOR_DEFAULTTONEAREST*/);
        GetDpiForMonitor(mon, dpiType, out dpiX, out dpiY);
    }

    //https://msdn.microsoft.com/en-us/library/windows/desktop/dd145062(v=vs.85).aspx
    [DllImport("User32.dll")]
    private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags);

    //https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
    [DllImport("Shcore.dll")]
    private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY);
}

//https://msdn.microsoft.com/en-us/library/windows/desktop/dn280511(v=vs.85).aspx
public enum DpiType
{
    Effective = 0,
    Angular = 1,
    Raw = 2,
}
  

Quick note: Works only with Windows 8 + .

There are three means of scaling, look at documentation to know more.

It's easy to emulate the code on a console:

private IEnumerable<string> Display(DpiType type)
{
    foreach (var screen in System.Windows.Forms.Screen.AllScreens)
    {
        uint x, y;
        screen.GetDpi(type, out x, out y);
        yield return screen.DeviceName + " - dpiX=" + x + ", dpiY=" + y;
    }
}

void Main(string[] args)
{
    Console.WriteLine(string.Join("\n", Display(DpiType.Angular)));
    Console.WriteLine(string.Join("\n", Display(DpiType.Effective)));
    Console.WriteLine(string.Join("\n", Display(DpiType.Raw)));
    // pausa a execução
    Console.ReadLine();
}

I got the answer from .

    
14.08.2017 / 07:06