In Windows 7 gibt es Einstellungen für die Anzeige (Systemsteuerung -> Anzeige). Hiermit können Sie die Größe des Texts und anderer Elemente auf dem Bildschirm ändern. Ich benötige diese Einstellung, um einige Funktionen in meiner C # -Anwendung basierend auf dem Einstellungswert ein- und ausschalten zu können. Ist das möglich?
74
Antworten:
Diese Einstellung ist die Bildschirm-DPI oder Punkte pro Zoll.
Lesen Sie es so:
float dpiX, dpiY; Graphics graphics = this.CreateGraphics(); dpiX = graphics.DpiX; dpiY = graphics.DpiY;
Ich denke nicht, dass es im Moment möglich ist, dass die X- und Y-Werte unterschiedlich sind. Ein Wert von 96 entspricht einer Skalierung von 100% (kleiner), 120 einer Skalierung von 125% (mittel) und 144 einer Skalierung von 150% (größer). Benutzer können jedoch andere Werte als diese Standardwerte festlegen.
Beachten Sie, dass die von Ihnen beobachteten Werte möglicherweise einer DPI-Virtualisierung unterliegen, sofern Ihre Anwendung nicht als DPI-fähig deklariert wird.
quelle
this
ist einfach ein beliebiges Steuerelement. msdn.microsoft.com/en-us/library/…Sowohl Graphics.DpiX als auch DeviceCap.LOGPIXELSX geben in Surface Pro in allen Skalierungsstufen 96 zurück.
Stattdessen konnte ich den Skalierungsfaktor folgendermaßen berechnen:
[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% }
quelle
Der meiner Meinung nach einfachste Weg ist die Verwendung der
GetDeviceCaps
Funktion. Von 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 }
Und Verwendung:
Graphics g = Graphics.FromHwnd(IntPtr.Zero); IntPtr desktop = g.GetHdc(); int Xdpi = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSX); int Ydpi = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSY);
Bei diesem Ansatz müssen Sie Ihre App nicht als dpi-fähig markieren.
quelle
So können Sie es in WPF machen. Der Rückgabewert ist in den logischen Einheiten von WPF angegeben, die 1/96 Zoll entsprechen. Wenn Ihre Bildschirm-DPI auf 96 eingestellt ist, erhalten Sie den Wert 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
( Quelle )
quelle
Hier ist eine Lösung, die unter Windows 10 gut funktioniert. DPI-Erkennung oder ähnliches ist nicht erforderlich.
public static int GetWindowsScaling() { return (int)(100 * Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth); }
quelle
Ich verwende diese Methode in meiner Konsolenanwendung:
float dpiX, dpiY; using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero)) { dpiX = graphics.DpiX; dpiY = graphics.DpiY; }
quelle
Die Verwendung der Antwort von Farshid T als Basis funktioniert in jedem Skalierungsfaktor mit Ausnahme von 125%. Ich habe ungefähr 20 verschiedene Skalierungsfaktoren getestet, und der DPI gibt immer 96 zurück, außer wenn er auf 125% eingestellt ist, was einen DPI von 120 ergibt. 120/96 = 1,25. Ich bin mir nicht sicher, warum dies der Fall ist, aber dieser Code scheint für jede Skalierungseinstellung zu funktionieren.
[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
und Verwendung:
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... }
quelle
Verwenden Sie im Fall von WPF das folgende 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; }
quelle
Dies ist eine sehr alte Frage, aber seit Windows 8.1 kann man verschiedene andere Funktionen verwenden, wie z
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; } }
Damit dies unter Windows 10 ordnungsgemäß funktioniert, müssen Sie
app.manifest
Ihrem C # -Projekt Folgendes hinzufügen :<?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>
quelle
Ich denke, dies sollte Ihnen die Informationen liefern, nach denen Sie suchen:
http://www.pinvoke.net/default.aspx/user32.getsystemmetrics
http://pinvoke.net/default.aspx/Enums.SystemMetric
Bearbeiten - Oh, tut mir leid, es gibt einen einfacheren Weg, diese Informationen jetzt ohne Pinvoke zu erhalten.
http://msdn.microsoft.com/en-us/library/system.windows.forms.systeminformation.aspx
quelle
Eine vollständigere Version von Ric Gaudets Antwort:
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] public static extern int GetDeviceCaps(IntPtr hDC, int nIndex); public enum DeviceCap { VERTRES = 10, DESKTOPVERTRES = 117 } static double GetWindowsScreenScalingFactor(bool percentage = true) { //Create Graphics object from the current windows handle Graphics GraphicsObject = Graphics.FromHwnd(IntPtr.Zero); //Get Handle to the device context associated with this Graphics object IntPtr DeviceContextHandle = GraphicsObject.GetHdc(); //Call GetDeviceCaps with the Handle to retrieve the Screen Height int LogicalScreenHeight = GetDeviceCaps(DeviceContextHandle, (int)DeviceCap.VERTRES); int PhysicalScreenHeight = GetDeviceCaps(DeviceContextHandle, (int)DeviceCap.DESKTOPVERTRES); //Divide the Screen Heights to get the scaling factor and round it to two decimals double ScreenScalingFactor = Math.Round((double)PhysicalScreenHeight / (double)LogicalScreenHeight, 2); //If requested as percentage - convert it if (percentage) { ScreenScalingFactor *= 100.0; } //Release the Handle and Dispose of the GraphicsObject object GraphicsObject.ReleaseHdc(DeviceContextHandle); GraphicsObject.Dispose(); //Return the Scaling Factor return ScreenScalingFactor; }
quelle