WinForm删除边框、圆角边框
WinForm删除边框
最近使用WinForm做界面美化,需要修改边框样式,但是原生控件边框样式难以扩展。上网没有搜到满意的边框样式修改资料,自行解决后记录下。
主要代码如下
protected override void WndProc(ref System.Windows.Forms.Message m)
{
//重绘消息WM_PAINT
if (m.Msg == 0xF)
{
base.WndProc(ref m);
//获取设备环境
IntPtr hDC = GetWindowDC(m.HWnd);
if (hDC != IntPtr.Zero)
{
//获取画布
Graphics g = Graphics.FromHdc(hDC);
//消锯齿
g.SmoothingMode = SmoothingMode.AntiAlias;
//边框路径
GraphicsPath borderPath = CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2); //新边框路径
borderPath.AddRectangle(new Rectangle(0, 0, this.Width - 1, this.Height - 1)); //原边框路径
borderPath.CloseAllFigures(); //封闭路径
//使用背景色覆盖边框区域
g.DrawPath(new Pen(BackColor), borderPath); //覆盖边框
g.FillPath(new SolidBrush(BackColor), borderPath); //覆盖边框包含区域
//绘制新边框、如果只是删除边框的话,不绘制即可
g.DrawPath(new Pen(CurrentBorderColor), CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2));
g.Dispose();
ReleaseDC(m.HWnd, hDC);
}
}
else
{
base.WndProc(ref m);
}
}
基本思想就是在界面重绘后,使用背景色覆盖边框区域,再重新绘制边框。下面是以此实现的圆角时间选择控件,以供参考
public class RoundedDateTimePicker : DateTimePicker
{
/// <summary>
/// 当前边框颜色
/// </summary>
private Color CurrentBorderColor;
/// <summary>
/// 边框颜色
/// </summary>
public Color BorderColor { get; set; } = Color.FromArgb(230, 230, 230);
/// <summary>
/// 边框颜色_鼠标进入控件
/// </summary>
public Color EnterBorderColor { get; set; } = Color.FromArgb(0, 0, 0);
/// <summary>
/// 边框颜色_获取焦点
/// </summary>
public Color FocusBorderColor { get; set; } = Color.FromArgb(62, 123, 250);
/// <summary>
/// 边框圆角半径
/// </summary>
public int Radius { get; set; } = 8;
public RoundedDateTimePicker()
{
InitializeComponent();
this.CurrentBorderColor = this.BorderColor;
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
//重绘消息WM_PAINT
if (m.Msg == 0xF)
{
base.WndProc(ref m);
//获取设备环境
IntPtr hDC = GetWindowDC(m.HWnd);
if (hDC != IntPtr.Zero)
{
//获取画布
Graphics g = Graphics.FromHdc(hDC);
//消锯齿
g.SmoothingMode = SmoothingMode.AntiAlias;
//边框路径
GraphicsPath borderPath = CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2); //新边框路径
borderPath.AddRectangle(new Rectangle(0, 0, this.Width - 1, this.Height - 1)); //原边框路径
borderPath.CloseAllFigures(); //封闭路径
//使用背景色覆盖边框区域
g.DrawPath(new Pen(BackColor), borderPath); //覆盖边框
g.FillPath(new SolidBrush(BackColor), borderPath); //覆盖边框包含区域
//绘制新边框
g.DrawPath(new Pen(CurrentBorderColor), CreateBorderPath(new Rectangle(0, 0, this.Width - 1, this.Height - 1), Radius * 2));
g.Dispose();
ReleaseDC(m.HWnd, hDC);
}
}
else
{
base.WndProc(ref m);
}
}
[DllImport("User32.dll")]
private static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
private void InitializeComponent()
{
this.SuspendLayout();
//
// RoundedDateTimePicker
//
this.Enter += new System.EventHandler(this.OnEntered);
this.Leave += new System.EventHandler(this.OnLeft);
this.MouseEnter += new System.EventHandler(this.OnMouseEntered);
this.MouseLeave += new System.EventHandler(this.OnMouseLeft);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OnMouseMove);
this.ResumeLayout(false);
}
private GraphicsPath CreateBorderPath(Rectangle rect, int diameter)
{
GraphicsPath path = new GraphicsPath();
path.AddArc(rect.Left, rect.Top, diameter, diameter, 180, 90);
path.AddLine(rect.Left + diameter, rect.Top, rect.Right - diameter, rect.Top);
path.AddArc(rect.Right - diameter, rect.Top, diameter, diameter, 270, 90);
path.AddLine(rect.Right, rect.Top + diameter, rect.Right, rect.Bottom - diameter);
path.AddArc(rect.Right - diameter, rect.Bottom - diameter, diameter, diameter, 0, 90);
path.AddLine(rect.Right - diameter, rect.Bottom, rect.Left + diameter, rect.Bottom);
path.AddArc(rect.Left, rect.Bottom - diameter, diameter, diameter, 90, 90);
path.AddLine(rect.Left, rect.Bottom - diameter, rect.Left, rect.Top + diameter);
path.CloseAllFigures();
return path;
}
private void RefreshBorder()
{
if (this.Focused)
this.CurrentBorderColor = FocusBorderColor;
else if (this.RectangleToScreen(this.ClientRectangle).Contains(MousePosition))
this.CurrentBorderColor = EnterBorderColor;
else
this.CurrentBorderColor = BorderColor;
}
private void OnMouseEntered(object sender, EventArgs e)
{
this.RefreshBorder();
}
private void OnMouseLeft(object sender, EventArgs e)
{
this.RefreshBorder();
}
private void OnEntered(object sender, EventArgs e)
{
this.RefreshBorder();
}
private void OnLeft(object sender, EventArgs e)
{
this.RefreshBorder();
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
this.RefreshBorder();
}
}