How to get the right DPI?

Asked

Viewed 39 times

0

I’m trying to get the DPI from the monitor, but it always returns 96, I researched and discovered many 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}");

1 answer

1

Try to circumvent with Winapi. First, you will have to add these references:

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

It is possible to obtain the DPI of all monitors installed with calls from GetDpiForMonitor:

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: Only works with Windows 8+.

There are three means of scale, look at the documentation to learn more.

It’s very easy to emulate 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 here.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.