none
Benutzerdefinierte Skalierung RRS feed

  • Frage

  • Hallo zusammen,

    meine Frage bezieht sich auf Windows10 pro., VisualStudio2017, VB.net.
    Klickt mann mit rechter Maustaste auf Desktop, kann man die Anzeigeeinstellungen aufrufen. Dort gibt esu.a. die Möglichkeit, unter Skalierung und Anordnung für die Größe von Text, Apps einen prozentualen Wert einzustellen, wodurch bspw. WinForm-Benutzeroberflächen entsprechend skaliert auf dem Screen dargestellt werden.

    Nun möchte ich mein Programm auf verschiedene PCs portieren, die jeder seine eigene Einstellung wie siehe oben haben.
    Das Problem ist für mich, mittels meines Programms diesen Prozentwert irgendwie/irgendwo auszulesen, um entsprechend in meinem Programm reagieren zu können.

    Wie und mit welchen Befehlen ist das zu realisieren?

    Grüße-


    Dietrich

    Samstag, 6. April 2019 15:25

Antworten

  • Hi Dietrich,
    hier mal eine Demo mit 2 Möglichkeiten für Windows Forms:

    Imports System.Runtime.InteropServices
    
    Public Class Form13
    
      Private lbl As New Label With {.Dock = DockStyle.Top}
      Private Sub Form13_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Controls.Add(lbl)
    
        lbl.Text = $"Verhältnis Auflösung: {GetSystemDpi()} dpi, Skalierung: {GetScalingFactor() * 100}%"
      End Sub
    
      Private Function GetScalingFactor() As Double
        Using g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
          Dim hdc As IntPtr = g.GetHdc()
          Dim LogicalScreenHeight As Integer = GetDeviceCaps(hdc, DeviceCaps.VERTRES)
          Dim PhysicalScreenHeight As Integer = GetDeviceCaps(hdc, DeviceCaps.DESKTOPVERTRES)
          g.ReleaseHdc(hdc)
          Dim ScreenScalingFactor As Double = PhysicalScreenHeight / LogicalScreenHeight
          Return ScreenScalingFactor ' 1.25 = 125%
        End Using
      End Function
    
      Public Function GetSystemDpi() As Integer
        Using g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
          Dim hdc As IntPtr = g.GetHdc()
          Dim virtualWidth As Integer = GetDeviceCaps(hdc, DeviceCaps.HORZRES)
          Dim physicalWidth As Integer = GetDeviceCaps(hdc, DeviceCaps.DESKTOPHORZRES)
          g.ReleaseHdc(hdc)
          Return CType(96 * physicalWidth / virtualWidth, Integer)
        End Using
      End Function
    
      Private Enum DeviceCaps
        ' http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
    
        ''' <summary>
        ''' Logical pixels inch in X
        ''' </summary>
        LOGPIXELSX = 88
    
        ''' <summary>
        ''' Horizontal width in pixels
        ''' </summary>
        HORZRES = 8
    
        ''' <summary>
        ''' Horizontal width of entire desktop in pixels
        ''' </summary>
        DESKTOPHORZRES = 118
    
        ''' <summary>
        ''' Vertical height in pixels
        ''' </summary>
        VERTRES = 10
    
        ''' <summary>
        ''' Vertical height of entire desktop in pixels
        ''' </summary>
        DESKTOPVERTRES = 117
      End Enum
    
      ''' <summary>
      ''' Retrieves device-specific information for the specified device.
      ''' </summary>
      ''' <param name="hdc">A handle to the DC.</param>
      ''' <param name="nIndex">The item to be returned.</param>
      <DllImport("gdi32.dll")>
      Private Shared Function GetDeviceCaps(hdc As IntPtr, nIndex As DeviceCaps) As Integer
      End Function
    
    End Class


    --
    Viele Grüsse / Best Regards
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Montag, 8. April 2019 04:48
  • Vielen Dank, Peter, für den Tipp mit Code!!!

    Ich werde das mal ausprobieren. Benötige es für die bessere Positionierung von Controls in Fenster oder Container bei entsprechender Bidschirmauflösung.

    Grüße-


    Dietrich

    • Als Antwort markiert dherrmann Dienstag, 23. April 2019 14:36
    Montag, 8. April 2019 07:22

Alle Antworten

  • Hi Dietrich,
    welche Technologie nutzt Du Windows Form oder WPF?

    Für WPF könnte folgendes dienen:

    Dim source = PresentationSource.FromVisual(this);
            dim dpiX, dpiY As Double
            if source IsNot Nothing Then
                dpiX = 96.0 * source.CompositionTarget.TransformToDevice.M11
                dpiY = 96.0 * source.CompositionTarget.TransformToDevice.M22
            End If


    --
    Viele Grüsse / Best Regards
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Sonntag, 7. April 2019 17:14
  • Danke Peter für den Tipp, allerdings bezieht sich meine Frage tatsächlich auf WinForms Projekte.

    Grüße-


    Dietrich

    Sonntag, 7. April 2019 17:23
  • Hi Dietrich,
    hier mal eine Demo mit 2 Möglichkeiten für Windows Forms:

    Imports System.Runtime.InteropServices
    
    Public Class Form13
    
      Private lbl As New Label With {.Dock = DockStyle.Top}
      Private Sub Form13_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Controls.Add(lbl)
    
        lbl.Text = $"Verhältnis Auflösung: {GetSystemDpi()} dpi, Skalierung: {GetScalingFactor() * 100}%"
      End Sub
    
      Private Function GetScalingFactor() As Double
        Using g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
          Dim hdc As IntPtr = g.GetHdc()
          Dim LogicalScreenHeight As Integer = GetDeviceCaps(hdc, DeviceCaps.VERTRES)
          Dim PhysicalScreenHeight As Integer = GetDeviceCaps(hdc, DeviceCaps.DESKTOPVERTRES)
          g.ReleaseHdc(hdc)
          Dim ScreenScalingFactor As Double = PhysicalScreenHeight / LogicalScreenHeight
          Return ScreenScalingFactor ' 1.25 = 125%
        End Using
      End Function
    
      Public Function GetSystemDpi() As Integer
        Using g As Graphics = Graphics.FromHwnd(IntPtr.Zero)
          Dim hdc As IntPtr = g.GetHdc()
          Dim virtualWidth As Integer = GetDeviceCaps(hdc, DeviceCaps.HORZRES)
          Dim physicalWidth As Integer = GetDeviceCaps(hdc, DeviceCaps.DESKTOPHORZRES)
          g.ReleaseHdc(hdc)
          Return CType(96 * physicalWidth / virtualWidth, Integer)
        End Using
      End Function
    
      Private Enum DeviceCaps
        ' http://pinvoke.net/default.aspx/gdi32/GetDeviceCaps.html
    
        ''' <summary>
        ''' Logical pixels inch in X
        ''' </summary>
        LOGPIXELSX = 88
    
        ''' <summary>
        ''' Horizontal width in pixels
        ''' </summary>
        HORZRES = 8
    
        ''' <summary>
        ''' Horizontal width of entire desktop in pixels
        ''' </summary>
        DESKTOPHORZRES = 118
    
        ''' <summary>
        ''' Vertical height in pixels
        ''' </summary>
        VERTRES = 10
    
        ''' <summary>
        ''' Vertical height of entire desktop in pixels
        ''' </summary>
        DESKTOPVERTRES = 117
      End Enum
    
      ''' <summary>
      ''' Retrieves device-specific information for the specified device.
      ''' </summary>
      ''' <param name="hdc">A handle to the DC.</param>
      ''' <param name="nIndex">The item to be returned.</param>
      <DllImport("gdi32.dll")>
      Private Shared Function GetDeviceCaps(hdc As IntPtr, nIndex As DeviceCaps) As Integer
      End Function
    
    End Class


    --
    Viele Grüsse / Best Regards
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Montag, 8. April 2019 04:48
  • Vielen Dank, Peter, für den Tipp mit Code!!!

    Ich werde das mal ausprobieren. Benötige es für die bessere Positionierung von Controls in Fenster oder Container bei entsprechender Bidschirmauflösung.

    Grüße-


    Dietrich

    • Als Antwort markiert dherrmann Dienstag, 23. April 2019 14:36
    Montag, 8. April 2019 07:22