How can I get the DPI in WPF?

Viewed 56435

How can I get the DPI in WPF?

10 Answers

This is how I managed to get a "scale factor" in WPF. My laptop's resolution is 1920x1440.

int resHeight = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;  // 1440
int actualHeight = SystemParameters.PrimaryScreenHeight;  // 960
double ratio = actualHeight / resHeight;
double dpi = resHeigh / actualHeight;  // 1.5 which is true because my settings says my scale is 150%

Use GetDeviceCaps function:

    static void Main(string[] args)
    {
        // 1.25 = 125%
        var dpi = GetDpi();
    }

    [DllImport("user32.dll")]
    public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

    [DllImport("user32.dll")]
    public static extern IntPtr GetDC(IntPtr hwnd);

    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

    private static float GetDpi()
    {
        IntPtr desktopWnd = IntPtr.Zero;
        IntPtr dc = GetDC(desktopWnd);
        var dpi = 100f;
        const int LOGPIXELSX = 88;
        try
        {
            dpi = GetDeviceCaps(dc, LOGPIXELSX);
        }
        finally
        {
            ReleaseDC(desktopWnd, dc);
        }
        return dpi / 96f;
    }

You can try using ManagementClass:

public static string GetDPI()
        {
            using (ManagementClass mc = new ManagementClass("Win32_DesktopMonitor"))
            {
                using (ManagementObjectCollection moc = mc.GetInstances())
                {

                    int PixelsPerXLogicalInch = 0; // dpi for x
                    int PixelsPerYLogicalInch = 0; // dpi for y

                    foreach (ManagementObject each in moc)
                    {
                        PixelsPerXLogicalInch = int.Parse((each.Properties["PixelsPerXLogicalInch"].Value.ToString()));
                        PixelsPerYLogicalInch = int.Parse((each.Properties["PixelsPerYLogicalInch"].Value.ToString()));
                    }
                    return PixelsPerXLogicalInch + "," + PixelsPerYLogicalInch;
                }
            }
        }

There are https://blogs.windows.com/buildingapps/2017/01/25/calling-windows-10-apis-desktop-application/#FJtMAIFjbtXiLQAp.97

January 25, 2017 3:54 pm

"Calling Windows 10 APIs From a Desktop Application" and

https://docs.microsoft.com/en-us/uwp/api/windows.devices.display.displaymonitor

"Display​Monitor Class"

Namespace: Windows.Devices.Display Assemblies:Windows.Devices.Display.dll, Windows.dll

Provides information about a display monitor device connected to the system.

These data include commonly used information from the monitor's Extended Display Identification Data (EDID, which is an industry-standard display descriptor block that nearly all monitors use to provide descriptions of supported modes and general device information) and DisplayID (which is a newer industry standard that provides a superset of EDID).

Raw​DpiX
Gets the physical horizontal DPI of the monitor (based on the monitor’s native resolution and physical size).

Raw​DpiY
Gets the physical vertical DPI of the monitor (based on the monitor’s native resolution and physical size).

Basic monitor info in Windows from 2006

https://docs.microsoft.com/en-us/windows/desktop/wmicoreprov/msmonitorclass

MSMonitorClass class

WmiMonitorRawEEdidV1Block class

WmiMonitorBasicDisplayParams class

MaxHorizontalImageSize ( EDID byte 21 )

MaxVerticalImageSize ( EDID byte 22 )

( Sizes in EDID are in centimeters above and in millimeters in EDID Detailed Timing Descriptor

12 Horizontal image size, mm, 8 lsbits (0–4095 mm, 161 in)
13 Vertical image size, mm, 8 lsbits (0–4095 mm, 161 in)
14 Bits 7–4 Horizontal image size, mm, 4 msbits
Bits 3–0 Vertical image size, mm, 4 msbits

)

and

https://social.msdn.microsoft.com/Forums/vstudio/en-US/e7bb9384-b343-4543-ac0f-c98b88a7196f/wpf-wmi-just-get-an-empty-string

Related