title: How can I get the scale factor of all my monitors?
body: <p>Microsoft can't figure out how to help me, so I have to ask here.</p>
  
  <p>I have three monitors...</p>
  
  <ul>
  <li>Screen 1: 3840 x 2160, scaling 150% </li>
  <li>Screen 2: 1920 x 1200, scaling 100% </li>
  <li>Screen 3: 1920 x 1200, scaling 100%</li>
  </ul>
  
  <p>I need in <code>VB.net</code> or <code>C#</code> to get the scaling of each monitors.</p>
  
  <p>Microsoft advises me to use this code:</p>
  
  <pre class="lang-vb prettyprint-override"><code>Private Declare Function GetDeviceCaps Lib "gdi32.dll" (hdc As IntPtr, nIndex As Integer) As Integer
  
  Public Enum DeviceCap
      VERTRES = 10
      DESKTOPVERTRES = 117
  End Enum
  
  Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
      For Each screen As Forms.Screen In Forms.Screen.AllScreens
          Dim pnt = New System.Drawing.Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1)
          Dim mon = MonitorFromPoint(pnt, 2)
          Dim fac As Single = GetScalingFactor(mon)
          Console.WriteLine($"Factor: {fac}")
      Next
  End Sub
  
  Private Function GetScalingFactor(monitorHandle As IntPtr) As Single
      Dim g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
      Dim desktop As IntPtr = g.GetHdc()
      Dim LogicalScreenHeight As Integer = GetDeviceCaps(desktop, CInt(DeviceCap.VERTRES))
      Dim PhysicalScreenHeight As Integer = GetDeviceCaps(desktop, CInt(DeviceCap.DESKTOPVERTRES))
      Dim ScreenScalingFactor As Single = CSng(PhysicalScreenHeight) / CSng(LogicalScreenHeight)
      Return ScreenScalingFactor
  End Function
  </code></pre>
  
  <p>But it returns a scale of 1 for all my screens.</p>
  
  <p>I need it to be independent of my app being dpiAware or not, so I have to read it from the screen control panel somehow.</p>
  
  <p>The solution must work on both Windows 10 and Windows Server 2012 R2 Remote Desktop clients.</p>