Click here to Skip to main content
15,887,267 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have the code below to round off the edges of my form.

I have several forms and this code is present on each of them

Is it possible to put this code in a class and call it in each of the forms to simplify?

C#
private int borderRadius = 30;
private int borderSize = 4;
private Color borderColor = Color.FromArgb(240, 185, 11);

[DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
private extern static void ReleaseCapture();
[DllImport("user32.DLL", EntryPoint = "SendMessage")]
private extern static void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int lParam);
private void FMain_MouseDown(object sender, MouseEventArgs e)
{
    ReleaseCapture();
    SendMessage(this.Handle, 0x112, 0xf012, 0);
}
private GraphicsPath GetRoundedPath(Rectangle rect, float radius)
{
    GraphicsPath path = new GraphicsPath();
    float curveSize = radius * 2F;

    path.StartFigure();
    path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90);
    path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90);
    path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90);
    path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90);
    path.CloseFigure();
    return path;
}
private void FormRegionAndBorder(Form form, float radius, Graphics graph, Color borderColor, float borderSize)
{
    if (this.WindowState != FormWindowState.Minimized)
    {
        using (GraphicsPath roundPath = GetRoundedPath(form.ClientRectangle, radius))
        using (Pen penBorder = new Pen(borderColor, borderSize))
        using (Matrix transform = new Matrix())
        {
            graph.SmoothingMode = SmoothingMode.AntiAlias;
            form.Region = new Region(roundPath);
            if (borderSize >= 1)
            {
                Rectangle rect = form.ClientRectangle;
                float scaleX = 1.0F - ((borderSize + 1) / rect.Width);
                float scaleY = 1.0F - ((borderSize + 1) / rect.Height);

                transform.Scale(scaleX, scaleY);
                transform.Translate(borderSize / 1.6F, borderSize / 1.6F);

                graph.Transform = transform;
                graph.DrawPath(penBorder, roundPath);
            }
        }
    }
}

private void FMain_Paint(object sender, PaintEventArgs e)
{
    FormRegionAndBorder(this, borderRadius, e.Graphics, borderColor, borderSize);
}


What I have tried:

I tried this but I get several errors.. Am I on the right track?

using Bybit.Net.Enums;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static MetroFramework.Drawing.MetroPaint;

namespace BasicProject
{

    public class Rounded
    {
        private int borderRadius = 30;
        private int borderSize = 4;
        private Color borderColor = Color.FromArgb(240, 185, 11);
    }

    [DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
    private extern static void ReleaseCapture();
    [DllImport("user32.DLL", EntryPoint = "SendMessage")]
    private extern static void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int lParam);
    private void FMain_MouseDown(object sender, MouseEventArgs e)
    {
        ReleaseCapture();
        SendMessage(this.Handle, 0x112, 0xf012, 0);
    }
    private GraphicsPath GetRoundedPath(Rectangle rect, float radius)
    {
        GraphicsPath path = new GraphicsPath();
        float curveSize = radius * 3F;

        path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 80);
        path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 80);
        path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 80);
        path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 80, 80);
        return path;
    }
    private void FormRegionAndBorder(Form form, float radius, Graphics graph, Color borderColor, float borderSize)
    {
        if (this.WindowState != FormWindowState.Minimized)
        {
            using (GraphicsPath roundPath = GetRoundedPath(form.ClientRectangle, radius))
            using (Pen penBorder = new Pen(borderColor, borderSize))
            using (Matrix transform = new Matrix())
            {
                graph.SmoothingMode = SmoothingMode.AntiAlias;
                form.Region = new Region(roundPath);
                if (borderSize >= 2)
                {
                    Rectangle rect = form.ClientRectangle;
                    float scaleX = 1.0F - ((borderSize + 2) / rect.Width);
                    float scaleY = 1.0F - ((borderSize + 2) / rect.Height);

                    transform.Translate(borderSize / 1.6F, borderSize / 1.6F);
                    graph.DrawPath(penBorder, roundPath);
                }
            }
        }
    }

    private void FMain_Paint(object sender, PaintEventArgs e)
    {
        FormRegionAndBorder(this, borderRadius, e.Graphics, borderColor, borderSize);
    }
Posted
Updated 27-Nov-23 9:18am
v3
Comments
Richard MacCutchan 27-Nov-23 15:27pm    
"I get several errors.. Am I on the right track?"
Since you have not shown us the errors we cannot say.
PIEBALDconsult 27-Nov-23 15:38pm    
Derive a new custom Form and use that.

I'd suggest to create a "template" window. Then every form you'll create in a future should inherit from that form.

More at:
Form inheritance - Windows Forms .NET Framework | Microsoft Learn[^]
How to: Inherit Forms Using the Inheritance Picker Dialog Box - Windows Forms .NET Framework | Microsoft Learn[^]
 
Share this answer
 
v2
Comments
Fred Lopez 28-Nov-23 2:08am    
@Maciej Los, Hi and thank you, according to your advice and links I tried this but during execution my forms are not rounded.. here is what I did: https://pastebin.com/vgqfF0dc

What do you call "template" window?
Chris Copeland 28-Nov-23 5:04am    
He means create a form that has all this code in it, and then have all your other forms inherit from this one form instead of the Form class. He's also provided some links in his solution which should guide you to doing that.
Maciej Los 29-Nov-23 5:59am    
Thank you, Cris for this tip.
Fred Lopez 28-Nov-23 10:23am    
Thanks
Maciej Los 29-Nov-23 5:57am    
You're very welcome.
Just throw the code in a static helper class...

C#
public static class FormHelper
{
	private GraphicsPath GetRoundedPath(Rectangle rect, float radius)
	{
		GraphicsPath path = new GraphicsPath();
		float curveSize = radius * 2F;

		path.StartFigure();
		path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90);
		path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90);
		path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90);
		path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90);
		path.CloseFigure();
		return path;
	}
	public void FormRegionAndBorder(Form form, float radius, Graphics graph, Color borderColor, float borderSize)
	{
		if (form.WindowState != FormWindowState.Minimized)
		{
			using (GraphicsPath roundPath = GetRoundedPath(form.ClientRectangle, radius))
			using (Pen penBorder = new Pen(borderColor, borderSize))
			using (Matrix transform = new Matrix())
			{
				graph.SmoothingMode = SmoothingMode.AntiAlias;
				form.Region = new Region(roundPath);
				if (borderSize >= 1)
				{
					Rectangle rect = form.ClientRectangle;
					float scaleX = 1.0F - ((borderSize + 1) / rect.Width);
					float scaleY = 1.0F - ((borderSize + 1) / rect.Height);

					transform.Scale(scaleX, scaleY);
					transform.Translate(borderSize / 1.6F, borderSize / 1.6F);

					graph.Transform = transform;
					graph.DrawPath(penBorder, roundPath);
				}
			}
		}
	}
}

Then to use:
C#
FormHelper.FormRegionAndBorder(this, borderRadius, e.Graphics, borderColor, borderSize);
 
Share this answer
 
v4
Comments
Maciej Los 27-Nov-23 16:57pm    
Another solution is to create "windows template" and then to inherit from it. :)

BTW: you missed "class" word in "public static FormHelper" statement.
Graeme_Grant 27-Nov-23 17:20pm    
Yes, that too ... but I was showing a more generic solution that could be used anywhere...

Missed class keyword - thanks, was a quick untested post. Fixing now.
Fred Lopez 28-Nov-23 2:02am    
@Graeme_Grant, Hi and thank you, I did exactly the same thing but I received several errors including:
IDE1007: The name 'FormRegionAndBorder' does not exist in the current context.
CS1014: Expected get or set accessor
Graeme_Grant 28-Nov-23 3:11am    
If it is a static class, it will be fine.
Fred Lopez 28-Nov-23 6:27am    
But I did "static class".
exactly like the code you posted.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900