C# Get the system DPI scaling ratio and resolution size
A solution to obtain the real desktop resolution when the desktop scaling ratio is not 100%
General method
System.Windows.Forms.Screen
class
// Get the current main screen resolution
int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int screenHeight = Screen.PrimaryScreen.Bounds.Height;
// Get the specified screen resolution
Screen secondaryScreen = Screen.AllScreens[1];
int secondaryScreenWidth = secondaryScreen.Bounds.Width;
int secondaryScreenHeight = secondaryScreen.Bounds.Height;
System.Windows.SystemParameters
class
// Get the current main screen resolution
double screenWidth = SystemParameters.PrimaryScreenWidth;
double screenHeight = SystemParameters.PrimaryScreenHeight;
// Get the resolution of all screens
double virtualScreenWidth = SystemParameters.VirtualScreenWidth;
double virtualScreenHeight = SystemParameters.VirtualScreenHeight;
A virtual screen refers to a logical screen composed of all physical screens, which can be used to display applications across multiple physical screens.
Both of these methods can obtain the screen resolution under normal circumstances – when the desktop scaling ratio is not 100%, the resolution obtained is ” “Real” resolution, but adjust the width and height of the content displayed on the screen according to the scaling ratio.
Windows API
At first I wrote a function that only gets the DPI scaling ratio, and then multiplied it manually. However, when I called System.Windows.Interop
, I couldn’t find this namespace on my colleague’s computer. I don’t know. For some reason, I later found an article with similar functions and fine-tuned it:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace ScreenDPIHelper
{
public class ScreenDPIHelper
{
#region Win32 API
[DllImport("user32.dll")]
static extern IntPtr GetDC(IntPtr ptr);
[DllImport("gdi32.dll")]
static extern int GetDeviceCaps(
IntPtr hdc, // handle to DC
int nIndex // index of capability
);
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
#endregion
#region DeviceCaps - Device properties constants
const int HORZRES = 8;
const int VERTRES = 10;
const int LOGPIXELSX = 88;
const int LOGPIXELSY = 90;
const int DESKTOPVERTRES = 117;
const int DESKTOPHORZRES = 118;
#endregion
#region attribute
// Get the current physical size of the screen resolution
public static Size WorkingArea
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
Size size = new Size();
size.Width = GetDeviceCaps(hdc, HORZRES);
size.Height = GetDeviceCaps(hdc, VERTRES);
ReleaseDC(IntPtr.Zero, hdc);
return size;
}
}
//The current system DPI_X size is generally 96
public static int DpiX
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
ReleaseDC(IntPtr.Zero, hdc);
return DpiX;
}
}
//The current system DPI_Y size is generally 96
public static int DpiY
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
int DpiX = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(IntPtr.Zero, hdc);
return DpiX;
}
}
// Get the actual desktop resolution size
public static Size DesktopResolution
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
Size size = new Size();
size.Width = GetDeviceCaps(hdc, DESKTOPHORZRES);
size.Height = GetDeviceCaps(hdc, DESKTOPVERTRES);
ReleaseDC(IntPtr.Zero, hdc);
return size;
}
}
// Get the width scaling percentage
public static float ScaleX
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
ReleaseDC(IntPtr.Zero, hdc);
return ScaleX;
}
}
// Get the height scaling percentage
public static floatScaleY
{
get
{
IntPtr hdc = GetDC(IntPtr.Zero);
float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);
ReleaseDC(IntPtr.Zero, hdc);
return ScaleY;
}
}
#endregion
}
}
This class uses two Win32 dynamic link libraries, user32.dll
and gdi32.dll
, and calls the functions in them. Such as:
GetDC
: This function returns the device context (DC) of the specified window client area or screen.ReleaseDC
: This function releases the specified device context (DC) obtained by theGetDC
function.GetDeviceCaps
: This function retrieves certain features of the specified device, such as resolution, color depth, printer output resolution, etc.
The defined constant parameters are:
HORZRES
: Horizontal resolution.VERTRES
: Vertical resolution.LOGPIXELSX
: Horizontal DPI.LOGPIXELSY
: Vertical DPI.DESKTOPVERTRES
: Vertical size of the true desktop resolution.DESKTOPHORZRES
: The horizontal size of the true desktop resolution.
The value of the parameter is the index of the corresponding parameter in the Win32 API.
The available parameters are:
WorkingArea
: Get the physical size of the screen resolution, that is, the size after removing the taskbar and other occupied screen space.DpiX
: Get the horizontal DPI of the current system. DPI is a unit of measurement that represents dots per inch, usually 96.DpiY
: Get the vertical DPI of the current system.DESKTOP
: Get the real desktop resolution size, including the taskbar and other parts that occupy space.ScaleX
: Get the scaling ratio of the width, that is, the ratio of the actual width of the current screen to the standard width (DESKTOPHORZRES).ScaleY
: Get the scaling ratio of the height, that is, the ratio of the actual height of the current screen to the standard height (DESKTOPVERTRES).
Reference documentation:
Platform call example
Use platform calls to marshal data
Identify functions in DLL
C# API to obtain the system DPI scaling factor and resolution size