2016-02-05 4 views
3

J'essaye de trouver un moyen de changer l'échelle d'affichage dans Windows 10 par programme en utilisant C#. Permettez-moi aussi de dire que je n'essaie pas de créer une application qui oblige automatiquement l'écran de l'utilisateur à changer de résolution/mise à l'échelle. C'est juste un outil pour moi de pouvoir basculer des balances du plateau, comme c'est quelque chose que je dois souvent faire pour tester. Donc volontairement conçu pour cette action.Comment est-ce que je peux changer l'échelle d'affichage de Windows 10 par programmation en utilisant C#

Donc, je suis en mesure de traquer ce que les entrées de registre (HKEY_CURRENT_USER \ Control Panel \ Desktop) sont définies lorsqu'un utilisateur fait manuellement via la boîte de dialogue officielle vu ci-dessous:

Windows 10 Display Scaling Dialog

Cependant , évidemment travailler avec le registre signifie que j'ai besoin de redémarrer la machine pour prendre effet.

Je suis conscient que vous pouvez utiliser le Pinvoke pour modifier la résolution d'écran: Setting my Display Resolution

Je me demandais s'il y a un moyen de changer cela « % » pour un écran trop donné? c'est-à-dire mon écran ci-dessus dit 150%, je voudrais pouvoir changer par programmation à travers la gamme complète de 100-500%.

Répondre

1

En recherchant exactement la même chose, j'ai trouvé votre question et trouvé une solution possible.

J'ai trouvé qu'une bascule par moniteur pour cette valeur% est dans le registre à Computer\HKEY_CURRENT_USER\Control Panel\Desktop\PerMonitorSettings\*monitorId*\DpiValue. il semble que la signification de la valeur dépend de l'écran (taille et ppp) voir this reddit post pour plus de détails.

Pour mon 24" écran 1080p 0 signifie 100% et 1 signifie 125%. This Technet Article semble être explainig les valeurs un peu.

Malheureusement, il ne suffit pas de changer la valeur de Registre. Mais vous pouvez actualiser la ppp en changeant la résolution après avoir écrit au registre.

le code suivant définit le dpi et passe alors une faible résolution et retour élevée pour déclencher la mise à jour dpi.

using System; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 
using Microsoft.Win32; 

namespace SetDpiScale 
{ 
    public partial class Form1 : Form 
    { 
     public enum DMDO 
     { 
      DEFAULT = 0, 
      D90 = 1, 
      D180 = 2, 
      D270 = 3 
     } 

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
     struct DEVMODE 
     { 
      public const int DM_PELSWIDTH = 0x80000; 
      public const int DM_PELSHEIGHT = 0x100000; 
      private const int CCHDEVICENAME = 32; 
      private const int CCHFORMNAME = 32; 

      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)] 
      public string dmDeviceName; 
      public short dmSpecVersion; 
      public short dmDriverVersion; 
      public short dmSize; 
      public short dmDriverExtra; 
      public int dmFields; 

      public int dmPositionX; 
      public int dmPositionY; 
      public DMDO dmDisplayOrientation; 
      public int dmDisplayFixedOutput; 

      public short dmColor; 
      public short dmDuplex; 
      public short dmYResolution; 
      public short dmTTOption; 
      public short dmCollate; 
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)] 
      public string dmFormName; 
      public short dmLogPixels; 
      public int dmBitsPerPel; 
      public int dmPelsWidth; 
      public int dmPelsHeight; 
      public int dmDisplayFlags; 
      public int dmDisplayFrequency; 
      public int dmICMMethod; 
      public int dmICMIntent; 
      public int dmMediaType; 
      public int dmDitherType; 
      public int dmReserved1; 
      public int dmReserved2; 
      public int dmPanningWidth; 
      public int dmPanningHeight; 
     } 

     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     static extern int ChangeDisplaySettings([In] ref DEVMODE lpDevMode, int dwFlags); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      ChangeDPI(0); // 100% 
     } 
     private void button2_Click(object sender, EventArgs e) 
     { 
      ChangeDPI(1); // 125% 
     } 

     void ChangeDPI(int dpi) 
     { 
      RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel", true); 

      key = key.OpenSubKey("Desktop", true); 
      key = key.OpenSubKey("PerMonitorSettings", true); 
      key = key.OpenSubKey("*monitor id where to change the dpi*", true); // my second monitor here 

      key.SetValue("DpiValue", dpi); 

      SetResolution(1920, 1080); // this sets the resolution on primary screen 
      SetResolution(2560, 1440); // returning back to my primary screens default resolution 
     } 

     private static void SetResolution(int w, int h) 
     { 
      long RetVal = 0; 

      DEVMODE dm = new DEVMODE(); 

      dm.dmSize = (short)Marshal.SizeOf(typeof(DEVMODE)); 

      dm.dmPelsWidth = w; 
      dm.dmPelsHeight = h; 

      dm.dmFields = DEVMODE.DM_PELSWIDTH | DEVMODE.DM_PELSHEIGHT; 


      RetVal = ChangeDisplaySettings(ref dm, 0); 
     } 
    } 
} 
+0

le problème avec e est la solution est que je ne vois sur aucun ordinateur PerMonitorSettings gagner 10 dans le registre, ou je ne peux voir qu'un seul moniteur. La solution avec changement de résolution ne fonctionne pas avec le paramètre LogPixels global. –