Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

vb.net - Rounded Rectangle Not Accurate

Every sample code I've ever found for drawing rounded rectangles using GDI+ goes something like this (lifted and slightly modified from BobPowell.net):

  Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles Panel1.Paint
    e.Graphics.Clear(SystemColors.Window)
    e.Graphics.SmoothingMode = SmoothingMode.None

    Call DrawRoundRect(e.Graphics, Pens.Red, 10, 10, 48, 24, 6)
  End Sub

  Public Sub DrawRoundRect(ByVal g As Graphics, ByVal p As Pen, ByVal x As Single, ByVal y As Single, ByVal width As Single, ByVal height As Single, ByVal radius As Single)
    Using gp As New GraphicsPath()
      gp.StartFigure()
      gp.AddArc(x + width - radius, y, radius * 2, radius * 2, 270, 90)
      gp.AddArc(x + width - radius, y + height - radius, radius * 2, radius * 2, 0, 90)
      gp.AddArc(x, y + height - radius, radius * 2, radius * 2, 90, 90)
      gp.AddArc(x, y, radius * 2, radius * 2, 180, 90)
      gp.CloseFigure()
      g.DrawPath(p, gp)
    End Using
  End Sub

This produces a rounded rectangle where only the top left corner is accurate.

AntiAliasing has to be turned off because it is going through a remote desktop connection, and I can't depend on it being available. Besides, I am looking for a crisp rounded rectangle.

enter image description here

I've tried resizing the other corners and changing the pen alignments, but nothing seems to produce a simple, accurate rounded rectangle.

Is there a way to draw a better rounded rectangle than this in good old winforms?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I have found the best solution to be just old-school Windows API:

Private Sub DrawRoundRect(ByVal g As Graphics, ByVal r As Rectangle)
  Dim hDC As IntPtr = g.GetHdc
  Dim hPen As IntPtr = CreatePen(PS_SOLID, 0, ColorTranslator.ToWin32(Color.Red))
  Dim hOldPen As IntPtr = SelectObject(hDC, hPen)
  SelectObject(hDC, GetStockObject(NULL_BRUSH))
  RoundRect(hDC, r.Left, r.Top, r.Right - 1, r.Bottom - 1, 12, 12)
  SelectObject(hDC, hOldPen)
  DeleteObject(hPen)
  g.ReleaseHdc(hDC)
End Sub

This produces the symmetrical rounded rectangle I've been looking for:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...