如何获得Windows显示设置?

在Windows 7中有显示设置(控制面板 – >显示)。 它允许更改屏幕上的文本和其他项目的大小。 我需要得到这个设置才能打开/closures我的C#应用​​程序根据设置值的一些function。 那可能吗?

这个设置是屏幕DPI,或者每英寸的点数。

像这样读取它:

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

我认为现在不可能X和Y值有所不同。 值为96对应于100%字体缩放(较小),120对应于125%缩放(中等),144对应于150%缩放(较大)。 但是,用户可以设置这些标准以外的值。

请注意,除非您的应用程序被声明为DPI,否则您观察到的值可能会受到DPI虚拟化的限制。

在所有缩放级别下,Surface.DpiX和DeviceCap.LOGPIXELSX都可以在Surface Pro上返回96。

相反,我设法通过这种方式来计算比例因子:

 [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% } 

我认为最简单的方法是使用GetDeviceCaps函数。 来自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 } 

和用法:

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

在这种方法中,您无需将您的应用程序标记为dpi识别。

这是你如何在WPF中做到这一点。 返回值是WPF的逻辑单位,等于1/96英寸。 所以如果你的屏幕DPI设置为96,你会得到1的值。

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

( 来源 )

在WPF中使用下面的代码片段,

 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; } 

我在控制台应用程序中使用这种方式:

 float dpiX, dpiY; using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero)) { dpiX = graphics.DpiX; dpiY = graphics.DpiY; } 

使用Farshid T的答案作为基础,在每个比例因子下工作,除了125%。 我testing了大约20个不同的比例因子,DPI总是返回96,除非设置为125%,DPI为120. 120/96 = 1.25。 不知道为什么是这种情况,但这段代码似乎适用于任何比例设置。

  [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 

和用法:

  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... } 

我认为这应该为您提供您正在寻找的信息:

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

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

编辑 – 哦,对不起,它看起来像现在有一个更简单的方法来获取这个信息,而没有pinvoke,

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

这是一个非常古老的问题,但是从Windows 8.1开始,可以使用其他函数,比如GetDpiForWindow

在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; } } 

为了在Windows 10周年中正常工作,您需要将一个app.manifest添加到您的C#项目中:

 <?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>