How to get windows display settings?

In Windows 7 (Control Panel β†’ Display), the setting is set. It allows you to resize text and other elements on the screen. I need to configure this parameter to enable / disable some functions in my C # application based on the value of the parameter. Is it possible?

+62
c # windows dpi
May 12 '11 at 11:45
source share
10 answers

This setting is a DPI screen or dots per inch.

Read it like this:

float dpiX, dpiY; Graphics graphics = this.CreateGraphics(); dpiX = graphics.DpiX; dpiY = graphics.DpiY; 

I do not think that at the moment it is possible that the values ​​of X and Y are different. A value of 96 corresponds to 100% scaling of the font (less), 120 corresponds to 125% scaling (medium), and 144 corresponds to 150% scaling (more). However, users can set values ​​other than these standard values.

Keep in mind that if your application is not declared as DPI, then the values ​​you observe may be subjected to DPI virtualization.

+40
May 12 '11 at 12:01
source share

Both .DpiX and DeviceCap.LOGPIXELSX graphs return 96 on the Surface Pro at all zoom levels.

Instead, I was able to calculate the scale factor as follows:

 [DllImport("gdi32.dll")] static extern int GetDeviceCaps(IntPtr hdc, int nIndex); public enum DeviceCap { VERTRES = 10, DESKTOPVERTRES = 117, // http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html } private float getScalingFactor() { Graphics g = Graphics.FromHwnd(IntPtr.Zero); IntPtr desktop = g.GetHdc(); int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES); int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES); float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight; return ScreenScalingFactor; // 1.25 = 125% } 
+67
Jan 30 '14 at 7:23
source share

The easiest way, in my opinion, is to use the GetDeviceCaps function. From pinvoke.net :

 [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] public static extern int GetDeviceCaps(IntPtr hDC, int nIndex); public enum DeviceCap { /// <summary> /// Logical pixels inch in X /// </summary> LOGPIXELSX = 88, /// <summary> /// Logical pixels inch in Y /// </summary> LOGPIXELSY = 90 // Other constants may be founded on pinvoke.net } 

And use:

 Graphics g = Graphics.FromHwnd(IntPtr.Zero); IntPtr desktop = g.GetHdc(); int Xdpi = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSX); int Ydpi = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSY); 

In this approach, you do not need to mark your application with the trend.

+14
May 12 '11 at 13:21
source share

Here is how you can do it in WPF. The return value is in WPF logical units that are 1/96 of an inch. Therefore, if your DPI for the screen is set to 96, you will get a value of 1.

 Matrix m = PresentationSource.FromVisual(Application.Current.MainWindow).CompositionTarget.TransformToDevice; double dx = m.M11; // notice it divided by 96 already double dy = m.M22; // notice it divided by 96 already 

( source )

+9
Jan 11 '13 at
source share

In the case of WPF, use the following snippet,

 PresentationSource source = PresentationSource.FromVisual(this); double dpiX, dpiY; if (source != null) { dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11; dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22; } 
+6
Jun 18 '14 at 11:00
source share

I use this method in my console application:

 float dpiX, dpiY; using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero)) { dpiX = graphics.DpiX; dpiY = graphics.DpiY; } 
+6
Aug 10 '15 at 13:04 on
source share

Using Farshid T's answer as a base works in every scale factor, with the exception of 125%. I tested about 20 different scaling factors, and DPI always returns as 96, unless set to 125%, which returns DPI 120. 120/96 = 1.25. Not sure why this is, but this code works for any scale settings.

  [DllImport("gdi32.dll")] static extern int GetDeviceCaps(IntPtr hdc, int nIndex); public enum DeviceCap { VERTRES = 10, DESKTOPVERTRES = 117, LOGPIXELSY = 90, // http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html 

and use:

  Graphics g = Graphics.FromHwnd(IntPtr.Zero); IntPtr desktop = g.GetHdc(); int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES); int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES); int logpixelsy = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSY); float screenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight; float dpiScalingFactor = (float)logpixelsy / (float)96; if (screenScalingFactor > 1 || dpiScalingFactor > 1) { // do something nice for people who can't see very well... } 
+4
Nov 18 '15 at 22:42
source share

This is a very old question, but with Windows 8.1 you can use various other functions like GetDpiForWindow

In C #:

 [DllImport("user32.dll")] static extern int GetDpiForWindow(IntPtr hWnd); public float GetDisplayScaleFactor(IntPtr windowHandle) { try { return GetDpiForWindow(windowHandle) / 96f; } catch { // Or fallback to GDI solutions above return 1; } } 

For the Windows 10 anniversary to work properly, you need to add app.manifest to your C # project:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <!-- The combination of below two tags have the following effect : 1) Per-Monitor for >= Windows 10 Anniversary Update 2) System < Windows 10 Anniversary Update --> <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware> </windowsSettings> </application> </assembly> 
+3
Apr 17 '17 at 12:28
source share

Here is a solution that works great on Windows 10. There is no need for DPI awareness or anything.

 public static int GetWindowsScaling() { return (int)(100 * Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth); } 
+2
Jun 11 '18 at 21:42
source share

I think this should provide you with the information you are looking for:

http://www.pinvoke.net/default.aspx/user32.getsystemmetrics

http://pinvoke.net/default.aspx/Enums.SystemMetric

Edit - oh, sorry, it seems like there is now an easier way to get this information without pinvoke,

http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.aspx

+1
May 12 '11 at 11:48
source share



All Articles