vb.netwinformsgraphics

How to make shapes, drawn on a form, resilient to changes in display's resolution / scale


An elegant solution for drawing polygons on a form was proposed by Jimi, as part of an answer to the question Why am I getting an extra line when drawing polygons? (see attached code).
I designed the app in VS2022 at scale 100%, DPI aware, on a machine with 1920x1200 resolution (first machine).
When running the app on a machines with 2160x15440 resolution and 150% scale, the size and the position of the shape changes (second machine). What needs modifying or adding to the code or to the environmental settings to prevent this happening?
Any suggestions would be highly appreciated.

Public Class Form1
    Dim centerPoint As PointF = New PointF(200, 100)
    Dim numberOfSides As Integer = 0
    Const skew As Single = Math.PI * 1.5F ' Corrects the rotation

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
        MyBase.OnPaint(e)
        If numberOfSides < 3 Then Return
        Dim polygon = CreatePolygon(radius:=70, numberOfSides, centerPoint)

        Using blackPen As New Pen(Color.Black, 2)
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            e.Graphics.DrawPolygon(blackPen, polygon)
        End Using
    End Sub

    Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged
        numberOfSides = CInt(ListBox1.SelectedItem)
        Me.Invalidate()
    End Sub

    Public Function CreatePolygon(radius As Single, sides As Integer, center As PointF) As PointF()
        Dim polygon = New PointF(sides - 1) {}
        Dim angle As Single = 360.0F / sides * CSng(Math.PI / 180.0F)

        For side As Integer = 0 To sides - 1
            polygon(side) = New PointF(
            CSng(center.X + radius * Math.Cos(skew + side * angle)),
            CSng(center.Y + radius * Math.Sin(skew + side * angle)))
        Next
        Return polygon
    End Function

End Class

Second machine First machine


Solution

  • I believe the problem occurs because the application does not handle different DPI (Dots Per Inch) settings correctly.

    The hardcoded values for centerPoint and radius are not adapted to the DPI scaling of the second computer, which leads to a changed size and position of the polygon.

    You should dynamically create centerPoint and radius.