C#WinForm自定义控件样式(textBox,comboBox,form,radiobutton,checkbox)

  • Post author:
  • Post category:其他


1.自定义comboBox控件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestFromStyleChange
{
    /// <summary>
    /// 自定义combobox控件
    /// 增加边框,
    /// </summary>
    #region 需要注意的地方
        //DrawMode=OwnerDrawVariale
        //DropDownStyle=DropDownList
    #endregion
    class MyComboBox : ComboBox
    {
        #region 自定义属性
        private Color _BorderColor = Color.FromArgb(87, 100, 108);
        private Color _BackColor = Color.FromArgb(232, 233, 237);
        private ButtonBorderStyle _BorderStyle = ButtonBorderStyle.Solid;
        private int _ArrowWidth = 2;
        private Color _ArrowColor = Color.FromArgb(87, 100, 108);
        private bool _ArrowFlag = true;
        private Color _FontColor = Color.FromArgb(0, 0, 0);
        private Color _BoxBgEnColor = Color.FromArgb(225, 224, 224);
        private Color _BoxBgUnColor = Color.FromArgb(187, 187, 187);
        [Description("边框颜色"), Category("Set")]
        public Color BorderColor
        {
            set { this._BorderColor = value; }
            get { return _BorderColor; }
        }
        [Description("背景颜色"), Category("Set")]
        public Color BoxBackColor
        {
            set { this._BackColor = value; }
            get { return this._BackColor; }
        }
        [Description("边框样式"), Category("Set")]
        public ButtonBorderStyle BoxBorderStyle
        {
            set { this._BorderStyle = value; }
            get { return this._BorderStyle; }
        }
        [Description("下拉箭头宽度"), Category("Set")]
        public int ArrowWidth
        {
            set { this._ArrowWidth = value; }
            get { return this._ArrowWidth; }
        }
        [Description("下拉箭头颜色"), Category("Set")]
        public Color ArrowColor
        {
            set { this._ArrowColor = value; }
            get { return this._ArrowColor; }
        }
        [Description("是否绘制下拉箭头"), Category("Set")]
        public bool ArrowEnabled
        {
            set { this._ArrowFlag = value; }
            get { return this._ArrowFlag; }
        }
        [Description("字体颜色"), Category("UserSet")]
        public Color FontColor
        {
            set { this._FontColor = value; }
            get { return this._FontColor; }
        }
        [Description("下拉框可用时的背景颜色"), Category("UserSet")]
        public Color BoxBgEnColor
        {
            set { this._BoxBgEnColor = value; }
            get { return this._BoxBgEnColor; }
        }
        [Description("下拉框不可用时的背景颜色"), Category("UserSet")]
        public Color BoxBgUnColor
        {
            set { this._BoxBgUnColor = value; }
            get { return this._BoxBgUnColor; }
        }
        #endregion
        public MyComboBox()
        {
            //SetStyle(ControlStyles.UserPaint /*| ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor*/, true);
            this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint,
true);
            this.UpdateStyles();
        }
        //导入API函数
        [System.Runtime.InteropServices.DllImport("user32.dll ")]
        static extern IntPtr GetWindowDC(IntPtr hWnd);//返回hWnd参数所指定的窗口的设备环境。

        [System.Runtime.InteropServices.DllImport("user32.dll ")]
        static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); //函数释放设备上下文环境(DC)

        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            int ItemsCount = Items.Count;
            Rectangle rect = new Rectangle(0, 0, e.Bounds.Width - 1, e.Bounds.Height * ItemsCount - 2);

            e.Graphics.FillRectangle(new SolidBrush(_BackColor), rect);
            e.Graphics.DrawRectangle(new Pen(new SolidBrush(_BorderColor)), rect);
            for (int i = 0; i < Items.Count; i++)
            {
                if (SelectedItem != null)
                {
                    if (SelectedItem.ToString() == Items[i].ToString())
                    {
                        Rectangle rectSel = new Rectangle(1, e.Bounds.Height * (SelectedIndex), e.Bounds.Width - 2, e.Bounds.Height - 2);
                        e.Graphics.FillRectangle(new SolidBrush(_BoxBgUnColor), rectSel);
                    }
                }
                e.Graphics.DrawString(Items[i].ToString(), Font, new SolidBrush(_FontColor), new PointF(0, i *(e.Bounds.Height == 0 ? 16 : e.Bounds.Height)));
            }
        }

        protected override void WndProc(ref Message m)
        {
            //if (m.Msg == 0x0014) // 禁掉清除背景消息
            //    return;
            base.WndProc(ref m);
            //WM_PAINT = 0xf; 要求一个窗口重画自己,即Paint事件时
            //WM_CTLCOLOREDIT = 0x133;当一个编辑型控件将要被绘制时发送此消息给它的父窗口;
            //通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色
            //windows消息值表,可参考:http://hi.baidu.com/dooy/blog/item/0e770a24f70e3b2cd407421b.html

            if (m.Msg == 0xf || m.Msg == 0x133)
            {
                IntPtr hDC = GetWindowDC(m.HWnd);
                if (hDC.ToInt32() == 0) //如果取设备上下文失败则返回
                {
                    return;
                }

                //建立Graphics对像
                Graphics g = Graphics.FromHdc(hDC);
                Rectangle rect = new Rectangle(0, 0, Width, Height);
                Rectangle rect2 = new Rectangle(1, 1, Width - 2, Height - 2);
                //画边框的 
                ControlPaint.DrawBorder(g, rect, _BorderColor, _BorderStyle);
                //画坚线
                //ControlPaint.DrawBorder(g, new Rectangle(Width - Height, 0, Height, Height), Color.Red, ButtonBorderStyle.Solid);
                //g.DrawLine(new Pen(Brushes.Blue, 2), new PointF(this.Width - this.Height, 0), new PointF(this.Width - this.Height, this.Height));
                Color backColor = Enabled ? _BoxBgEnColor : _BoxBgUnColor;
                string selValue = SelectedItem == null ? "" : SelectedItem.ToString();
                string Text = Enabled ? selValue : "";
                g.FillRectangle(new SolidBrush(backColor), rect2);
                //填充背景
                if (_ArrowFlag)
                {
                    //g.DrawLine(new Pen(_ArrowColor, _ArrowWidth), new PointF(this.Width - this.Height + 6, 6), new PointF(this.Width - this.Height + 11, 11));
                    //g.DrawLine(new Pen(_ArrowColor, _ArrowWidth), new PointF(this.Width - this.Height + 11, 11), new PointF(this.Width - this.Height + 16, 6));
                    g.DrawLines(new Pen(_ArrowColor, _ArrowWidth), new PointF[] { new PointF(this.Width - this.Height + 6, 6), new PointF(this.Width - this.Height + 11, 11), new PointF(this.Width - this.Height + 16, 6) });
                }
                g.DrawString(Text, Font, new SolidBrush(_FontColor), 1, 2);
                //释放DC  
                ReleaseDC(m.HWnd, hDC);
            }
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            this.ResumeLayout(false);

        }
    }
}

  1. 自定义TextBox(增加边框)

    `using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Drawing;

    using System.Linq;

    using System.Runtime.InteropServices;

    using System.Text;

    using System.Threading.Tasks;

    using System.Windows.Forms;

namespace TestFromStyleChange

{


///

/// 自定义输入框控件

/// 增加了边框颜色属性

///

#region 使用时需要注意的地方

//无

#endregion

public partial class MyTextBox : TextBox

{

    private Rectangle m_rcClient = Rectangle.Empty;
    private Color _coBorder = Color.Black;


    //protected override CreateParams CreateParams
    //{
    //    get
    //    {
    //        CreateParams cparams = base.CreateParams;
    //        BorderStyle border = this.BorderStyle;

    //        if (!(border == BorderStyle.Fixed3D))
    //        {
    //            cparams.ExStyle &= ~NativeMethods.WS_EX_CLIENTEDGE;
    //            cparams.Style &= ~8388608;

    //            switch (border)
    //            {
    //                // Unlike other controls, text box doesn't draw its single border in the NC area!
    //                case BorderStyle.Fixed3D:
    //                case BorderStyle.FixedSingle:
    //                    // 使一个视窗具有凹陷边框
    //                    cparams.ExStyle = cparams.ExStyle | NativeMethods.WS_EX_CLIENTEDGE | NativeMethods.WS_EX_WINDOWEDGE;
    //                    break;
    //            }
    //        }

    //        return cparams;
    //    }
    //}
    [Description("边框颜色"),Category("UserSet")]
    public Color BorderColor
    {
        get { return this._coBorder; }
        set { this._coBorder = value; }
    }


    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case NativeMethods.WM_PAINT:
                this.OnWmNcPaint(ref m);
                break;
            case NativeMethods.WM_NCPAINT:
                this.OnWmNcPaint(ref m);
                return;
        }


        base.WndProc(ref m);
    }

    private void OnWmNcPaint(ref Message m)
    {
        NativeMethods.RECT rcWnd = new NativeMethods.RECT();
        NativeMethods.GetWindowRect(m.HWnd, ref rcWnd);

        int intWidth = rcWnd.Width;
        int intHeight = rcWnd.Height;

        int width = rcWnd.Width;
        int height = rcWnd.Height;

        IntPtr hRgn = NativeMethods.CreateRectRgn(0, 0, width, height);
        if (hRgn != IntPtr.Zero)
        {
            IntPtr hDc = NativeMethods.GetWindowDC(m.HWnd);
            if (hDc != IntPtr.Zero)
            {
                IntPtr memDc = NativeMethods.CreateCompatibleDC(hDc);
                if (memDc != IntPtr.Zero)
                {
                    IntPtr hBmp = NativeMethods.CreateCompatibleBitmap(hDc, width, height);
                    if (hBmp != IntPtr.Zero)
                    {
                        IntPtr hObj = NativeMethods.SelectObject(memDc, hBmp);

                        if (m.WParam.ToInt32() != 1)
                        {
                            IntPtr tmpRgn = NativeMethods.CreateRectRgn(0, 0, 0, 0);

                            NativeMethods.CombineRgn(tmpRgn, m.WParam, IntPtr.Zero, NativeMethods.RGN_COPY);
                            NativeMethods.OffsetRgn(tmpRgn, -rcWnd.left, -rcWnd.top);
                            NativeMethods.CombineRgn(hRgn, hRgn, tmpRgn, NativeMethods.RGN_AND);

                            NativeMethods.DeleteObject(tmpRgn);
                        }

                        using (Graphics g = Graphics.FromHdc(memDc))
                        {
                            RenderNCArea(g, width, height, true);
                        }

                        NativeMethods.SelectClipRgn(hDc, hRgn);
                        NativeMethods.ExcludeClipRect(hDc, m_rcClient.X, m_rcClient.Y, m_rcClient.Right, m_rcClient.Bottom);

                        NativeMethods.BitBlt(hDc, 0, 0, rcWnd.Width, rcWnd.Height, memDc, 0, 0, 0x00CC0020/*SRCCOPY*/ );

                        NativeMethods.SelectObject(memDc, hObj);
                        NativeMethods.DeleteObject(hBmp);
                    }

                    NativeMethods.DeleteDC(memDc);
                }
                NativeMethods.DeleteDC(hDc);
            }

            IntPtr hTmp = NativeMethods.CreateRectRgn(m_rcClient.Left, m_rcClient.Top, m_rcClient.Right, m_rcClient.Bottom);
            if (hTmp != IntPtr.Zero)
            {
                NativeMethods.CombineRgn(hRgn, hRgn, hTmp, NativeMethods.RGN_AND);
                NativeMethods.OffsetRgn(hRgn, rcWnd.left, rcWnd.top);
                NativeMethods.DeleteObject(hTmp);

                Message msg = new Message();

                msg.Msg = m.Msg;
                msg.HWnd = m.HWnd;
                msg.WParam = hRgn;

                base.WndProc(ref msg);
            }
            NativeMethods.DeleteObject(hRgn);
        }

        m.Result = IntPtr.Zero;
    }

    private void RenderNCArea(Graphics g, int width, int height, bool bDrawBorder)
    {
        Rectangle rc = new Rectangle(0, 0, width, height);

        using (Brush brush = new SolidBrush(this.BackColor))
        {
            g.FillRectangle(brush, 0, 0, width, height);
        }

        if (bDrawBorder)
        {
            DrawBorders(rc, g);
        }

    }

    private void DrawBorders(Rectangle rc, Graphics g)
    {
        ControlPaint.DrawBorder(g, rc, this.BorderColor, ButtonBorderStyle.Solid);
    }

}

public class NativeMethods
{
    internal const int WS_EX_CLIENTEDGE = 512 /*0x0200*/;
    internal const int WS_EX_WINDOWEDGE = 0x0100;
    internal const int WM_PAINT = 15; // 0x000f
    internal const int WM_NCPAINT = 133; // 0x0085


    internal const int RGN_AND = 1;
    internal const int RGN_OR = 2;
    internal const int RGN_XOR = 3;
    internal const int RGN_DIFF = 4;
    internal const int RGN_COPY = 5;

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int left;
        public int top;
        public int right;
        public int bottom;

        public RECT(Rectangle rect)
        {
            this.bottom = rect.Bottom;
            this.left = rect.Left;
            this.right = rect.Right;
            this.top = rect.Top;
        }

        public RECT(int left, int top, int right, int bottom)
        {
            this.bottom = bottom;
            this.left = left;
            this.right = right;
            this.top = top;
        }

        public static RECT FromXYWH(int x, int y, int width, int height)
        {
            return new RECT(x, y, x + width, y + height);
        }

        public int Width
        {
            get
            {
                return this.right - this.left;
            }
        }
        public int Height
        {
            get
            {
                return this.bottom - this.top;
            }
        }

        public override /*Object*/ string ToString()
        {
            return String.Concat(
              "Left = ",
              this.left,
              " Top ",
              this.top,
              " Right = ",
              this.right,
              " Bottom = ",
              this.bottom);
        }

        public static implicit operator Rectangle(RECT rect)
        {
            return Rectangle.FromLTRB(rect.left, rect.top, rect.right, rect.bottom);
        }

    }

    [DllImport("user32.dll")]
    internal static extern bool GetWindowRect(IntPtr hwnd, ref RECT lpRect);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    internal static extern IntPtr CreateRectRgn(int x1, int y1, int x2, int y2);

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    internal static extern IntPtr GetWindowDC(IntPtr hWnd);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    internal static extern IntPtr CreateCompatibleDC(IntPtr hDC);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    internal static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int width, int height);

    [DllImport("gdi32", CharSet = CharSet.Auto, ExactSpelling = true)]
    internal static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    internal static extern int CombineRgn(IntPtr hRgn, IntPtr hRgn1, IntPtr hRgn2, int nCombineMode);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    public static extern int OffsetRgn(IntPtr hrgn, int nXOffset, int nYOffset);

    [DllImport("gdi32")]
    internal static extern bool DeleteObject(IntPtr hObject);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    internal static extern int SelectClipRgn(IntPtr hDC, IntPtr hRgn);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
    public static extern int ExcludeClipRect(IntPtr hdc, int nLeft, int nTop, int nRight, int nBottom);

    [DllImport("gdi32.dll")]
    internal static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, Int32 dwRop);

    [DllImport("gdi32", EntryPoint = "DeleteDC", CharSet = CharSet.Auto, ExactSpelling = true)]
    internal static extern bool DeleteDC(IntPtr hDC);
}

}

`

4. 自定义radioButton

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestFromStyleChange
{
    /// <summary>
    /// 自定义单选按钮
    /// </summary>
    // 引用时,需要设置一下,
    //AutoSize=false,设置Size的宽高,
    public partial class MyNewRadioButton : RadioButton
    {
        #region 自定义属性
        private Color _BorderBgColor = Color.FromArgb(232, 233, 237);
        private Color _FontColor = Color.FromArgb(0, 0, 0);
        [Description("背景色"), Category("UserSet")]
        public Color BorderBgColor
        {
            set { this._BorderBgColor = value; }
            get { return _BorderBgColor; }
        }
        [Description("字体颜色"),Category("UserSet")]
        public Color FontColor
        {
            set { this._FontColor = value; }
            get { return this._FontColor; }
        }
        #endregion
        public MyNewRadioButton()
        {
        }
        #region 重写paint事件
        /// <summary>
        /// 样式1,图标采用图片,重写paint事件
        /// RadioButtonSel 选中时图标的名称
        /// RadioButtonUnSel 未选中时图标的名称
        /// </summary>
        /// <param name="pevent"></param>
        protected override void OnPaint(PaintEventArgs pevent)
        {
            Graphics g = pevent.Graphics;
            Rectangle rect = new Rectangle(-1, -1, Width + 1, Height + 1);
            //抗锯齿处理 
            g.SmoothingMode = SmoothingMode.AntiAlias;
            //1.填充背景颜色
            g.FillRectangle(new SolidBrush(_BorderBgColor), rect);
            //绘制左边图形
            Rectangle rectCircle = new Rectangle(0, 0, Height, Height);
            if (!Checked)
            {
                //绘制未选中样式
                g.DrawImage(Properties.Resources.RadioButtonSel, 0, 0, Height, Height);
            }
            else
            {
                //绘制选中样式
                g.DrawImage(Properties.Resources.RadioButtonUnSel, 0, 0, Height, Height);
            }
            //绘制右边文字
            g.DrawString(Text, Font, new SolidBrush(_FontColor), Height, (Height - Font.Size) / 2);
        }
        #endregion
        #region 样式1.图标采用绘图方式
        //private Color _BorderColor = Color.FromArgb(87, 100, 108);
        //private int _BorderWidth = 2;
        //[Description("边框颜色"), Category("UserSet")]
        //public Color BorderColor
        //{
        //    set { this._BorderColor = value; }
        //    get { return _BorderColor; }
        //}
        //[Description("边框宽度"), Category("UserSet")]
        //public int BorderWidth
        //{
        //    set { this._BorderWidth = value; }
        //    get { return _BorderWidth; }
        //}
        /// <summary>
        /// 重写paint事件 ,样式1
        /// </summary>
        /// <param name="pevent"></param>
        //protected override void OnPaint(PaintEventArgs pevent)
        //{
        //    Graphics g = pevent.Graphics;
        //    Rectangle rect = new Rectangle(-1, -1, Width + 1, Height + 1);
        //    //抗锯齿处理 
        //    g.SmoothingMode = SmoothingMode.AntiAlias;
        //    //1.填充背景颜色
        //    g.FillRectangle(new SolidBrush(_BorderBgColor), rect);
        //    //绘制左边图形
        //    Rectangle rectCircle = new Rectangle(0, 0, Height, Height);
        //    if (!Checked)
        //    {
        //        //绘制未选中样式
        //        rectCircle.Inflate(-(Height / 20) - 2, -(Height / 20) - 2);//矩形内缩2单位
        //        using (Pen pen = new Pen(_BorderColor, _BorderWidth))
        //        {
        //            //2.画一个圆
        //            g.DrawEllipse(pen, rectCircle);
        //        }
        //        rectCircle.Inflate(-(Height / 20), -(Height / 20));
        //        //3.填充背景
        //        g.FillEllipse(new SolidBrush(_BorderBgColor), rectCircle);
        //    }
        //    else
        //    {
        //        //绘制选中样式
        //        rectCircle.Inflate(-(Height / 20) - 2, -(Height / 20) - 2);
        //        using (Pen pen = new Pen(_BorderColor, _BorderWidth))
        //        {
        //            //2.画一个圆
        //            g.DrawEllipse(pen, rectCircle);
        //        }
        //        rectCircle.Inflate(-(Height / 6), -(Height / 6));
        //        g.FillEllipse(new SolidBrush(_BorderColor), rectCircle);
        //    }
        //    //绘制右边文字
        //    g.DrawString(Text, Font, new SolidBrush(Color.Black), Height, (Height - Font.Size) / 2);
        //}
        #endregion
        #region 样式3
        /// <summary>
        /// 样式3.重写paint事件 
        /// </summary>
        /// <param name="pevent"></param>
        //protected override void OnPaint(PaintEventArgs pevent)
        //{
        //    Graphics g = pevent.Graphics;
        //    Rectangle radioButtonrect = new Rectangle(0, 0, Width - 1, Height - 1);
        //    int _BorderWidth = 2;
        //    Color _BorderColor = Color.FromArgb(87, 100, 108); //#e8e9ed
        //    Color _BorderBgColor = Color.FromArgb(232, 233, 237);//#57646c
        //    Color _BorderBgCheckedColor = Color.FromArgb(255, 255, 255);
        //    g.SmoothingMode = SmoothingMode.AntiAlias;//抗锯齿处理 
        //                                              //1.方形边框
        //    using (Pen pen = new Pen(_BorderColor, _BorderWidth))
        //    {
        //        g.DrawRectangle(pen, radioButtonrect);
        //    }
        //    if (!Checked)
        //    {
        //        //绘制未选中样式
        //        radioButtonrect.Inflate(-_BorderWidth, -_BorderWidth);//矩形内缩2单位
        //        g.FillRectangle(new SolidBrush(_BorderBgColor), radioButtonrect);
        //        radioButtonrect.Inflate(-2, -2);//矩形内缩5单位
        //        using (Pen pen = new Pen(_BorderColor, _BorderWidth))
        //        {
        //            radioButtonrect.Inflate(-_BorderWidth, -_BorderWidth);
        //            g.DrawEllipse(pen, radioButtonrect);
        //        }
        //        radioButtonrect.Inflate(-4, -4);
        //        g.FillEllipse(new SolidBrush(_BorderColor), radioButtonrect);
        //        //radioButtonrect.Inflate(10, 10);//矩形大小还原
        //    }
        //    else
        //    {
        //        绘制选中样式
        //        radioButtonrect.Inflate(-_BorderWidth, -_BorderWidth);
        //        g.FillRectangle(new SolidBrush(_BorderBgCheckedColor), radioButtonrect);
        //        radioButtonrect.Inflate(-3, -3);
        //        g.FillEllipse(new SolidBrush(_BorderColor), radioButtonrect);
        //        radioButtonrect.Inflate(-4, -4);
        //        g.FillEllipse(new SolidBrush(_BorderBgCheckedColor), radioButtonrect);
        //        radioButtonrect.Inflate(10, 10);//矩形大小还原
        //    }
        //}
        #endregion
    }
}

  1. 自定义checkBox
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestFromStyleChange
{
    /// <summary>
    /// 自定义checkbox
    /// </summary>
    #region 需要注意的地方
    //设置AutoSize=false; 设置宽高
    #endregion
    public partial class MyCheckBox : CheckBox
    {
        #region 自定义变量
        private Color _BorderBgColor = Color.FromArgb(232, 233, 237);
        private Color _FontColor = Color.FromArgb(0, 0, 0);

       
        [Description("背景颜色"), Category("UserSet")]
        public Color BorderBgColor
        {
            set { this._BorderBgColor = value; }
            get { return this._BorderBgColor; }
        }
        [Description("字体颜色"), Category("UserSet")]
        public Color FontColor
        {
            set { this._FontColor = value; }
            get { return this._FontColor; }
        }
        #endregion
        public MyCheckBox()
        {

        }
        #region 图标采用图片
        //checkBoxSel选中时的图标名字
        //checkBox未选中时的图标名字
        protected override void OnPaint(PaintEventArgs pevent)
        {
            //base.OnPaint(pevent);
            Graphics g = pevent.Graphics;
            //填充背景
            Rectangle rect = new Rectangle(0, 0, Width, Height);
            g.FillRectangle(new SolidBrush(_BorderBgColor), rect);
            //绘制左边复选框
            if (Checked)
            {
                //绘制选中时的对勾
                g.DrawImage(Properties.Resources.checkBoxSel, 2, 2, Height - 4, Height - 4);
            }
            else
            {
                g.DrawImage(Properties.Resources.CheckBoxUnSel, 2, 2, Height - 4, Height - 4);
            }
            //绘制右边文字
            g.DrawString(Text, Font, new SolidBrush(_FontColor), Height, (Height - Font.Size) / 2);
        }
        #endregion
        #region 图标采用绘制方式
        //private Color _BorderColor = Color.FromArgb(87, 100, 108);
        //[Description("边框颜色"), Category("UserSet")]
        //public Color BorderColor
        //{
        //    set { this._BorderColor = value; }
        //    get { return this._BorderColor; }
        //}
        //protected override void OnPaint(PaintEventArgs pevent)
        //{
        //    //base.OnPaint(pevent);
        //    Graphics g = pevent.Graphics;
        //    //填充背景
        //    Rectangle rect = new Rectangle(0, 0, Width, Height);
        //    g.FillRectangle(new SolidBrush(_BorderBgColor), rect);
        //    //绘制左边复选框
        //    Rectangle rectCircle = new Rectangle(0, 0, Height, Height);
        //    using (Pen pen = new Pen(new SolidBrush(_BorderColor)))
        //    {
        //        if (Checked)
        //        {
        //            //绘制选中时的对勾
        //            rectCircle.Inflate(-3, -3);
        //            g.FillRectangle(new SolidBrush(_BorderColor), rectCircle);
        //        }
        //        else
        //        {
        //            rectCircle.Inflate(-5, -5);
        //            g.DrawRectangle(pen, rectCircle);
        //        }
        //    }
        //    //绘制右边文字
        //    //Rectangle rectText = new Rectangle(Height, 0, Width-Height, Height);
        //    //g.FillRectangle(new SolidBrush(Color.Green), rectText);
        //    g.DrawString(Text, Font, new SolidBrush(_FontColor), Height, (Height - Font.Size) / 2);
        //}
        #endregion
    }
}

  1. 自定义form窗体
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestFromStyleChange
{
    public partial class MyForm_2 : Form
    {
        public MyForm_2()
        {
            InitializeComponent();
            //this.StartPosition = FormStartPosition.Manual;
            this.StartPosition = FormStartPosition.CenterScreen;
            //this.Location = (Point)new Size(200, 200);
        }
        #region 自定义属性
        private int _MaxBtnWidth = 22;
        private int _MaxBtnHeight = 20;
        private int _MaxLeft = 7;
        private int _MaxBorderWidth = 2;
        private Color _BorderColor = Color.Gray;
        [Description("边框颜色"), Category("UserSet")]
        public Color BorderColor
        {
            set { this.BorderColor = value; }
            get { return this._BorderColor; }
        }
        #endregion
        #region WindowsAPI
        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowDC(IntPtr hWnd);
        [DllImport("user32.dll")]
        private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        [DllImport("dwmapi.dll")]
        private static extern int DwmDefWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, out IntPtr result);
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        #endregion
        #region Windows系统消息
        private const int WM_PAINT = 0x000F;
        private const int WM_CREATE = 0x0001;
        private const int WM_NCCREATE = 0x0081;
        private const int WM_NCCALCSIZE = 0x0083;
        private const int WM_NCPAINT = 0x0085;//绘制客户区
        private const int WM_MOUSEMOVE = 0x0200;
        private const int WM_NCMOUSEMOVE = 0x00A0;
        private const int WM_NCACTIVATE = 0x0086;//绘制非客户区(标题栏)
        private const int WM_NCLBUTTONDOWN = 0x00A1;//鼠标点击
        private const int WM_NCHITTEST = 0x84;//命中测试
        private const int WM_SYSCOMMAND = 0x112;//系统菜单消息
        private const int SC_CLOSE = 0xF060;//关闭
        private const int SC_MINIMIZE = 0xF020;//最小化
        private const int SC_MAXIMIZE = 0xF030;//最大化
        private const int SC_MOVE = 0xF010;
        private const int SC_RESTORE = 0xF120;//恢复窗口
        //鼠标命中测试命中区域
        private const int HTCLIENT = 1;
        private const int HTCAPTION = 2;
        private const int HTLEFT = 10;
        private const int HTRIGHT = 11;
        private const int HTTOP = 12;
        private const int HTLEFTTOP = 13;
        private const int HTRIGHTTOP = 14;
        private const int HTBOTTOM = 15;
        private const int HTLEFTBOTTOM = 16;
        private const int HTRIGHTBOTTOM = 17;
        //拖动窗口实现缩放
        private const int WMSZ_LEFT = 0xF001;
        private const int WMSZ_RIGHT = 0xF002;
        private const int WMSZ_TOP = 0xF003;
        private const int WMSZ_LEFTTOP = 0xF004;
        private const int WMSZ_RIGHTTOP = 0xF005;
        private const int WMSZ_BOTTOM = 0xF006;
        private const int WMSZ_LEFTBOTTOM = 0xF007;
        private const int WMSZ_RIGHTBOTTOM = 0xF008;
        #endregion
        #region 自定义窗体边框大小
        int _Top = 30;
        int _Left = 8;
        int _Right = 8;
        int _Bottom = 8;
        #endregion
        #region 重写WndProc方法,完成窗体重绘
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_NCPAINT:
                case WM_NCACTIVATE://重绘标题栏
                    IntPtr vHandle = GetWindowDC(m.HWnd);
                    Graphics vGraphics = Graphics.FromHdc(vHandle);
                    DrawTitle(vGraphics);
                    ReleaseDC(m.HWnd, vHandle);
                    break;
                //case WM_NCHITTEST://命中测试,即获取鼠标点击的区域
                //    m.Result = HitTestNCA();
                //    break;
                case WM_NCLBUTTONDOWN://鼠标点击事件
                    #region 点击事件(实现窗体拖动、缩放、关闭、最大化、最小化)
                    switch (getMousePosition())
                    {
                        case SC_CLOSE://点击了关闭按钮
                            this.Close();
                            break;
                        case SC_MAXIMIZE://点击了最大化按钮
                            this.WindowState = this.WindowState != FormWindowState.Maximized ? FormWindowState.Maximized : FormWindowState.Normal;
                            break;
                        case SC_MINIMIZE://点击了最小化按钮
                            if (this.WindowState != FormWindowState.Minimized)
                            {
                                this.WindowState = FormWindowState.Minimized;
                            }
                            break;
                        case HTCAPTION: //点击标题栏拖动窗体
                            ReleaseCapture();//释放label1对鼠标的捕捉
                            SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
                            break;
                        case HTLEFT://拖动左边改变窗体大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_LEFT, 0);
                            break;
                        case HTRIGHT://拖动右边改变窗体大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_RIGHT, 0);
                            this.Invalidate();
                            break;
                        case HTTOP://拖动上面改变窗体大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_TOP, 0);
                            break;
                        case HTBOTTOM://拖动底部改变窗体大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_BOTTOM, 0);
                            break;
                        case HTLEFTTOP://拖动左上角改变大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_LEFTTOP, 0);
                            break;
                        case HTLEFTBOTTOM://拖动左下角改变大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_LEFTBOTTOM, 0);
                            break;
                        case HTRIGHTTOP://拖动右上角改变大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_RIGHTTOP, 0);
                            break;
                        case HTRIGHTBOTTOM://拖动右下角改变大小
                            ReleaseCapture();
                            SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_RIGHTBOTTOM, 0);
                            break;
                    }
                    #endregion
                    break;
                case WM_NCMOUSEMOVE:
                    //鼠标移动事件
                    vHandle = GetWindowDC(m.HWnd);
                    vGraphics = Graphics.FromHdc(vHandle);
                    Pen pen = new Pen(new SolidBrush(Color.White), _MaxBorderWidth);
                    Pen newPen = new Pen(new SolidBrush(Color.Red), _MaxBorderWidth);
                    switch (getMousePosition())
                    {
                        case SC_CLOSE:
                            DrawFunBtn(vGraphics, pen, pen, newPen, "Close");
                            break;
                        case SC_MAXIMIZE:
                            DrawFunBtn(vGraphics, newPen, pen, pen, "Max");
                            break;
                        case SC_MINIMIZE:
                            DrawFunBtn(vGraphics, pen, newPen, pen, "Min");
                            break;
                        default:
                            DrawFunBtn(vGraphics, pen, pen, pen, "Max");
                            break;
                    }
                    ReleaseDC(m.HWnd, vHandle);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }
        #endregion
        #region 绘制最大化、最小化、关闭按钮
        private void DrawFunBtn(Graphics vGraphics, Pen MaxPen, Pen MinPen, Pen ClosePen, string lastBtnName)
        {
            //Rectangle FunRect=new Rectangle ()
            int BaseX = Location.X;
            int BaseY = Location.Y;
            Rectangle rectClose = new Rectangle(Width - _Right - _MaxBtnWidth, _Bottom, _MaxBtnWidth, _MaxBtnHeight);
            Rectangle rectMax = new Rectangle(Width - _Right - _MaxBtnWidth * 2, _Bottom, _MaxBtnWidth, _MaxBtnHeight);
            Rectangle rectMin = new Rectangle(Width - _Right - _MaxBtnWidth * 3, _Bottom, _MaxBtnWidth, _MaxBtnHeight);
            if (lastBtnName == "Max")
            {
                vGraphics.DrawRectangle(MinPen, rectMin);
                vGraphics.DrawRectangle(ClosePen, rectClose);
                vGraphics.DrawRectangle(MaxPen, rectMax);
            }
            else if (lastBtnName == "Min")
            {
                vGraphics.DrawRectangle(ClosePen, rectClose);
                vGraphics.DrawRectangle(MaxPen, rectMax);
                vGraphics.DrawRectangle(MinPen, rectMin);
            }
            else
            {
                vGraphics.DrawRectangle(MinPen, rectMin);
                vGraphics.DrawRectangle(MaxPen, rectMax);
                vGraphics.DrawRectangle(ClosePen, rectClose);
            }
            //绘制最小化按钮
            vGraphics.DrawLine(MinPen, Width - _Right - _MaxBtnWidth * 3 + _MaxLeft, _Bottom + _MaxBtnHeight / 2, Width - _Right - _MaxLeft - _MaxBtnWidth * 2, _Bottom + _MaxBtnHeight / 2);
            //绘制关闭按钮
            Point plt = new Point(Width - _Right - _MaxBtnWidth + _MaxLeft, _Bottom + _MaxBtnHeight / 4);
            Point plb = new Point(Width - _Right - _MaxBtnWidth + _MaxLeft, _Bottom + _MaxBtnHeight * 3 / 4);
            Point prt = new Point(Width - _Right - _MaxLeft, _Bottom + _MaxBtnHeight / 4);
            Point prb = new Point(Width - _Right - _MaxLeft, _Bottom + _MaxBtnHeight * 3 / 4);
            vGraphics.DrawLine(ClosePen, plt, prb);
            vGraphics.DrawLine(ClosePen, plb, prt);
            plt.Offset(-_MaxBtnWidth, 0);
            plb.Offset(-_MaxBtnWidth, 0);
            prt.Offset(-_MaxBtnWidth, 0);
            prb.Offset(-_MaxBtnWidth, 0);
            //绘制最大化按钮             
            if (this.WindowState != FormWindowState.Maximized)
            {
                vGraphics.DrawLine(MaxPen, plt, plb);
                vGraphics.DrawLine(MaxPen, prt, prb);
                vGraphics.DrawLine(MaxPen, plt, prt);
                vGraphics.DrawLine(MaxPen, plb, prb);
            }
            else
            {
                plt.Offset(-1, 1);
                plb.Offset(-1, 1);
                prt.Offset(-1, 1);
                prb.Offset(-1, 1);
                vGraphics.DrawLine(MaxPen, plt, plb);
                vGraphics.DrawLine(MaxPen, prt, prb);
                vGraphics.DrawLine(MaxPen, plt, prt);
                vGraphics.DrawLine(MaxPen, plb, prb);
                plt.Offset(3, -3);
                plb.Offset(3, -3);
                prt.Offset(3, -3);
                prb.Offset(3, -3);
                vGraphics.DrawLine(MaxPen, plt, plb);
                vGraphics.DrawLine(MaxPen, prt, prb);
                vGraphics.DrawLine(MaxPen, plt, prt);
                vGraphics.DrawLine(MaxPen, plb, prb);
            }
        }
        #endregion
        #region 绘制标题栏
        private void DrawTitle(Graphics vGraphics)
        {
            #region 绘制边框
            vGraphics.FillRectangle(new SolidBrush(_BorderColor), new Rectangle(0, 0, Width, _Top)); //top
            vGraphics.FillRectangle(new SolidBrush(_BorderColor), new Rectangle(0, 0, _Left, Height));//left
            vGraphics.FillRectangle(new SolidBrush(_BorderColor), new Rectangle(0, Height - _Bottom, Width, _Bottom));//bottom
            vGraphics.FillRectangle(new SolidBrush(_BorderColor), new Rectangle(Width - _Right, 0, _Right, Height));//right
            #endregion
            #region 绘制标题栏文字、图标
            int left = 0, top = 0;
            if (ShowIcon)
            {
                int x = (_Top - Icon.Height) > 0 ? (_Top - Icon.Height) / 2 : _Bottom;
                Rectangle e = new Rectangle(x, x, _Top - _Bottom, _Top - _Bottom);
                vGraphics.DrawIcon(Icon, e);
                left += (_Top - Icon.Width) / 2 + Icon.Width;
            }
            top += (_Top - Convert.ToInt32(Font.Size)) / 2;
            left += 10;
            Rectangle TitleRectangle = new Rectangle(left, top, Width, _Top);
            vGraphics.DrawString(Text, Font, Brushes.BlanchedAlmond, TitleRectangle);
            #endregion
            #region 绘制最大化、最小化、关闭
            using (Pen pen = new Pen(new SolidBrush(Color.White), _MaxBorderWidth))
            {
                DrawFunBtn(vGraphics, pen, pen, pen, "Max");
            }
            #endregion
            vGraphics.Dispose();
        }
        #endregion
        #region 判断鼠标所在区域
        private int getMousePosition()
        {
            int BaseX = Location.X;
            int BaseY = Location.Y;
            //获取鼠标位置
            Point p = new Point(MousePosition.X, MousePosition.Y);
            Point p2 = PointToScreen(MousePosition);
            //以下待时式判断鼠标处于何处,并返回响应的值,优先级从高到低位为:边角-边缘-标题
            #region 边角判断
            //左上角判断
            Rectangle rectTopLeft = new Rectangle(BaseX, BaseY, _Left, _Left);

            if (rectTopLeft.Contains(p))
            {
                return HTLEFTTOP;
            }
            //右上角
            Rectangle rectTopRight = new Rectangle(BaseX + Width - _Right, BaseY, _Right, _Right);
            if (rectTopRight.Contains(p))
            {
                return HTRIGHTTOP;
            }
            //左下角
            Rectangle rectLeftBottom = new Rectangle(BaseX, BaseY + Height - _Bottom, _Left, _Bottom);
            if (rectLeftBottom.Contains(p))
            {
                return HTLEFTBOTTOM;
            }
            //右下角
            Rectangle rectRightBottom = new Rectangle(BaseX + Width - _Left, BaseY + Height - _Bottom, _Right, _Bottom);
            if (rectRightBottom.Contains(p))
            {
                return HTRIGHTBOTTOM;
            }
            #endregion
            #region 关闭、最大化、最小化按钮判断
            Rectangle rectClose = new Rectangle(BaseX + Width - _Right - _MaxBtnWidth, BaseY + _Bottom, _MaxBtnWidth, _MaxBtnHeight);
            if (rectClose.Contains(p))
            {
                return SC_CLOSE;
            }
            Rectangle rectMax = new Rectangle(BaseX + Width - _Right - _MaxBtnWidth * 2, BaseY + _Bottom, _MaxBtnWidth, _MaxBtnHeight);
            if (rectMax.Contains(p))
            {
                return SC_MAXIMIZE;
            }
            Rectangle rectMin = new Rectangle(BaseX + Width - _Right - _MaxBtnWidth * 3, BaseY + _Bottom, _MaxBtnWidth, _MaxBtnHeight);
            if (rectMin.Contains(p))
            {
                return SC_MINIMIZE;
            }
            #endregion
            #region 边缘判断
            //上边缘
            Rectangle rectTop = new Rectangle(BaseX, BaseY, Width, _Bottom);
            if (rectTop.Contains(p))
            {
                return HTTOP;
            }
            //左边媛
            Rectangle rectLeft = new Rectangle(BaseX, BaseY + _Bottom, _Left, Height);
            if (rectLeft.Contains(p))
            {
                return HTLEFT;
            }
            //右边媛
            Rectangle rectRight = new Rectangle(BaseX + Width - _Right, BaseY + _Bottom, _Right, Height);
            if (rectRight.Contains(p))
            {
                return HTRIGHT;
            }
            //下边缘
            Rectangle rectBottom = new Rectangle(BaseX, BaseY + Height - _Bottom, Width, _Bottom);
            if (rectBottom.Contains(p))
            {
                return HTBOTTOM;
            }
            #endregion
            #region 标题
            //标题栏
            Rectangle rectCaption = new Rectangle(BaseX, BaseY + _Bottom, Width, _Top - _Bottom);
            if (rectCaption.Contains(p))
            {
                return HTCAPTION;
            }
            #endregion
            return HTCLIENT;//返回客户区消息
        }
        #endregion
        #region 根据鼠标在窗体上的位置返回不同消息的值,用于模拟非客户消息
        private IntPtr HitTestNCA()
        {
            return new IntPtr(getMousePosition());
        }
        #endregion
    }
}



版权声明:本文为weixin_44777515原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。