Как получить настройки дисплея Windows?
есть настройка для отображения в Windows 7 (Панель управления -> дисплей). Это позволяет изменять размер текста и других элементов на экране. Мне нужно получить этот параметр, чтобы иметь возможность включать/выключать некоторые функции в моем приложении C# на основе значения параметра. Это возможно?
10 ответов:
этот параметр экрана DPI, или точек на дюйм.
читать это так:
float dpiX, dpiY; Graphics graphics = this.CreateGraphics(); dpiX = graphics.DpiX; dpiY = graphics.DpiY;
Я не думаю, что в данный момент возможно, чтобы значения X и Y были разными. Значение 96 соответствует 100% масштабированию шрифта (меньше), 120 соответствует 125% масштабированию (средний) и 144 соответствует 150% масштабированию (больше). Однако пользователи могут устанавливать значения, отличные от этих стандартных.
имейте в виду, что если ваше приложение не объявлено как DPI известно, что значения, которые вы наблюдаете, могут подлежать виртуализации DPI.
оба графика.DpiX и DeviceCap.LOGPIXELSX возвращает 96 на Surface Pro во всех уровнях масштабирования.
вместо этого мне удалось вычислить коэффициент масштабирования следующим образом:
[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
вот как это можно сделать в 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%. Я протестировал около 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... }
Это очень старый вопрос, но так как 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 anniversary, вам нужно добавить
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>
Я думаю, что это должно предоставить вам интересующую вас информацию:
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