2

I experimented with GraphicPaths and find that funny thing: DrawArc() with same ellipse width and height, but different start angle (0,90,180,270) are different Code:

            GraphicsPath pth = new GraphicsPath();
            pth.AddArc(10, 10, 16, 16, 180, 90);
            pth.AddArc( 40, 10, 16, 16, 270, 90);
            pth.AddArc( 40, 40, 16, 16, 0, 90);
            pth.AddArc( 10, 40, 16, 16, 90, 90);
            e.Graphics.FillPath(new SolidBrush(Color.FromArgb(100, 120, 200)), pth);

Expected:

Expected

But painted (only left top arc is correct):

But painted

How to fix that?

  • See the implementation [here](https://stackoverflow.com/a/54794097/7444103), for example. Note the use of the curve size to define the Point coordinates. Also, note the use of `float` measures (quite important, even with *static* objects). – Jimi Jun 27 '20 at 23:07
  • Try to create a `RectangleF` as the *container* for your graphics object, then use its coordinates to calculate the offsets. – Jimi Jun 27 '20 at 23:17
  • @Jimi, your first comment with link helped me. Offsets? I just draw this figure in random position on a form – Andrey059918 Jun 27 '20 at 23:23
  • The offsets are related to the `PointF` position (the `float x` and `float y` parameters) and, as a consequence, to the sizes of the shape's sides (the `float width` and `float height` parameters - note: all `float` values). These are all determined by a calculation (as shown in the example). That's why I suggested to create a shape using a `RectangleF` container. It's easier to *see* how and where the drawn shape differ from the rectangular one. – Jimi Jun 27 '20 at 23:36
  • Did you try setting `e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;`? While you're at it, you might also want `e.Graphics..SmoothingMode = SmoothingMode.HighQuality;` and possibly later you might want `e.Graphics.CompositingQuality = CompositingQuality.HighQuality;` – Wyck Jun 29 '20 at 00:04
  • For a better round corner, I ended up using [`CreateRoundRectRgn`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createroundrectrgn?WT.mc_id=DT-MVP-5003235), like this: [How to create a User Control with rounded corners?](https://stackoverflow.com/a/32991419/3110834) – Reza Aghaei Feb 13 '21 at 16:47

1 Answers1

1

To create a round rectangle region, I ended up using CreateRoundRectRgn:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect,
    int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);

enter image description here

public partial class RoundCornerControl : Control
{
    private int radius = 20;
    [DefaultValue(20)]
    public int Radius
    {
        get { return radius; }
        set { radius = value; this.RecreateRegion(); }
    }
    [System.Runtime.InteropServices.DllImport("gdi32.dll")]
    private static extern IntPtr CreateRoundRectRgn(int nLeftRect, int nTopRect,
        int nRightRect, int nBottomRect, int nWidthEllipse, int nHeightEllipse);
    private void RecreateRegion()
    {
        var bounds = ClientRectangle;
        this.Region = Region.FromHrgn(CreateRoundRectRgn(bounds.Left, bounds.Top,
            bounds.Right, bounds.Bottom, Radius, radius));
        this.Invalidate();
    }
    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        this.RecreateRegion();
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398