Come ottenere le impostazioni di visualizzazione di Windows?

C’è l’impostazione per Schermo in Windows 7 (Pannello di controllo -> Schermo). Permette di cambiare la dimensione del testo e altri elementi sullo schermo. Ho bisogno di ottenere questa impostazione per essere in grado di accendere / spegnere alcune funzionalità nella mia applicazione C # in base al valore di impostazione. È ansible?

Questa impostazione è il DPI dello schermo, o punti per pollice.

Leggilo così:

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

Non credo sia ansible in questo momento che i valori X e Y siano diversi. Un valore di 96 corrisponde al 100% di ridimensionamento dei caratteri (più piccolo), 120 corrisponde al 125% di ridimensionamento (medio) e 144 corrisponde al 150% di ridimensionamento (maggiore). Tuttavia, gli utenti sono in grado di impostare valori diversi da quelli standard.

Tieni presente che, a meno che la tua applicazione non sia dichiarata DPI, i valori che osservi potrebbero essere soggetti alla virtualizzazione DPI.

Sia graphics.DpiX che DeviceCap.LOGPIXELSX restituiscono 96 su Surface Pro in tutti i livelli di ridimensionamento.

Invece, sono riuscito a calcolare il fattore di scala in questo modo:

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

Il modo più semplice a mio parere è utilizzare la funzione GetDeviceCaps . Da pinvoke.net :

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

E l’uso:

 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 questo approccio non hai bisogno di contrassegnare la tua app in formato dpi.

Questo è come puoi farlo in WPF. Il valore di ritorno è nelle unità logiche di WPF, che sono uguali a 1 / 96th di pollice. Quindi se il DPI dello schermo è impostato su 96, si otterrà il valore 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 

( fonte )

In caso di WPF usa il seguente frammento,

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

Io uso in questo modo nella mia applicazione console:

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

Usando la risposta di Farshid T come base funziona in ogni fattore di scala, tranne il 125%. Ho testato circa 20 diversi fattori di ridimensionamento e il DPI ritorna sempre come 96, tranne quando impostato al 125%, che restituisce un DPI di 120. 120/96 = 1,25. Non sono sicuro del motivo per cui questo è il caso, ma questo codice sembra funzionare per qualsiasi impostazione di scala.

  [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 

e utilizzo:

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

Questa è una domanda molto vecchia, ma dal momento che Windows 8.1, si possono usare varie altre funzioni, come 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; } } 

Affinché funzioni correttamente in occasione dell’anniversario di Windows 10, devi aggiungere un app.manifest al tuo progetto C #:

 < ?xml version="1.0" encoding="UTF-8" standalone="yes"?>     PerMonitor True/PM    

Penso che questo dovrebbe fornirti le informazioni che stai cercando:

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

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

Modifica – oh scusa sembra che ci sia un modo più semplice per ottenere queste informazioni ora senza un pinvoke,

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

Ecco una soluzione che funziona bene in Windows 10. Non c’è bisogno di consapevolezza DPI o altro.

 public static int GetWindowsScaling() { return (int)(100 * Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth); }