利用GDI+制作背景颜色淡入淡出效果的按钮

用过QQ2009的网友都知道QQ主面板的界面非常炫丽,特别好看,鼠标移上去还有淡入淡出的效果。那这样效果是怎么做出来的呢?其实不难,只要自定义一个用户控件的外怪就可以了,用到GDI+技术和时钟控件来操作

首先我们在VS2008里面新建一个Windows窗体控件库的项目,系统会自动生成一个用户控件UserControl1.cs出来,我们就用默认的名字吧~~

本例子下载地址:https://files.cnblogs.com/mengxin523/自定义按钮控件.rar

程序所有代码如下:

 

using System;

using System.Data;

using System.Drawing;

using System.Collections;

using System.Windows.Forms;

using System.ComponentModel;

using System.Drawing.Drawing2D;

 

namespace MyButton

{

    public partial class UserControl1 : UserControl

    {

        private bool calledbykey = false;

        private State mButtonState = State.None;   //按钮的状态

        private Timer mFadeIn = new Timer();     //淡入的时钟

        private Timer mFadeOut = new Timer();    //淡出的时钟

        private int mGlowAlpha = 0;        //透明度

        private System.ComponentModel.Container components = null;

        public UserControl1()

        {

            InitializeComponent();

            //一下几个语句是对控件进行设置和对GDI+进行优化

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

            this.SetStyle(ControlStyles.DoubleBuffer, true);

            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            this.SetStyle(ControlStyles.ResizeRedraw, true);

            this.SetStyle(ControlStyles.Selectable, true);

            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            this.SetStyle(ControlStyles.UserPaint, true);

            this.UpdateStyles();

            this.BackColor = Color.Transparent;   //设置控件背景色透明

            mFadeIn.Interval = 20;   //淡入速度

            mFadeOut.Interval = 20;   //淡出速度

        }

        protected override void Dispose(bool disposing)

        {

            if (disposing)

            {

                if (components != null)

                {

                    components.Dispose();

                }

            }

            base.Dispose(disposing);

        }

        private void InitializeComponent()

        {

            this.Name = "MySystemButton";

            this.Size = new System.Drawing.Size(100, 32);

            this.Paint += new System.Windows.Forms.PaintEventHandler(this.VistaButton_Paint);

            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyUp);

            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyDown);

            this.MouseEnter += new System.EventHandler(this.VistaButton_MouseEnter);

            this.MouseLeave += new System.EventHandler(this.VistaButton_MouseLeave);

            this.MouseUp += new MouseEventHandler(VistaButton_MouseUp);

            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.VistaButton_MouseDown);

            this.GotFocus += new EventHandler(VistaButton_MouseEnter);

            this.LostFocus += new EventHandler(VistaButton_MouseLeave);

            this.mFadeIn.Tick += new EventHandler(mFadeIn_Tick);

            this.mFadeOut.Tick += new EventHandler(mFadeOut_Tick);

            this.Resize += new EventHandler(VistaButton_Resize);

        }

        enum State { None, Hover, Pressed };

        /// <summary>

        /// 按钮的样式

        /// </summary>

        public enum Style

        {

            /// <summary>

            /// Draw the button as normal

            /// </summary>

            Default,

            /// <summary>

            /// Only draw the background on mouse over.

            /// </summary>

            Flat

        };

        /// <summary>

        /// 用于设置按钮的用处

        /// </summary>

        public enum UseTo

        {

            Min, Close

        };

        UseTo Ut = UseTo.Close;    //默认作为关闭按钮

        [Category("UseTo"),

         DefaultValue(UseTo.Close),

         Browsable(true),

         Description("设置按钮的用处")]

        public UseTo UT

        {

            get

            {

                return Ut;

            }

            set

            {

                Ut = value;

                this.Invalidate();

            }

        }

        private string mText;

        /// <summary>

        /// 按钮上显示的文本

        /// </summary>

        [Category("Text"),

         Description("按钮上显示的文本.")]

        public string ButtonText

        {

            get { return mText; }

            set { mText = value; this.Invalidate(); }

        }

        private Color mForeColor = Color.White;

        /// <summary>

        /// 文本颜色

        /// </summary>

        [Category("Text"),

         Browsable(true),

         DefaultValue(typeof(Color), "White"),

         Description("文本颜色.")]

        public override Color ForeColor

        {

            get { return mForeColor; }

            set { mForeColor = value; this.Invalidate(); }

        }

        private ContentAlignment mTextAlign = ContentAlignment.MiddleCenter;

        /// <summary>

        /// 文本对齐方式

        /// </summary>

        [Category("Text"),

         DefaultValue(typeof(ContentAlignment), "MiddleCenter")]

        public ContentAlignment TextAlign

        {

            get { return mTextAlign; }

            set { mTextAlign = value; this.Invalidate(); }

        }

        private Image mImage;

        /// <summary>

        按钮上的图片

        /// </summary>

        [Category("Image"),

         DefaultValue(null)]

        public Image Image

        {

            get { return mImage; }

            set { mImage = value; this.Invalidate(); }

        }

 

        private ContentAlignment mImageAlign = ContentAlignment.MiddleLeft;

        /// <summary>

        按钮对齐方式

        /// </summary>

        [Category("Image"),

         DefaultValue(typeof(ContentAlignment), "MiddleLeft")]

        public ContentAlignment ImageAlign

        {

            get { return mImageAlign; }

            set { mImageAlign = value; this.Invalidate(); }

        }

        private Size mImageSize = new Size(24, 24);

        /// <summary>

        图片大小

        /// </summary>

        [Category("Image"),

         DefaultValue(typeof(Size), "24, 24")]

        public Size ImageSize

        {

            get { return mImageSize; }

            set { mImageSize = value; this.Invalidate(); }

        }

 

 

        private Style mButtonStyle = Style.Default;

        /// <summary>

按钮的样式

        /// </summary>

        [Category("Appearance"),

         DefaultValue(typeof(Style), "Default")]

        public Style ButtonStyle

        {

            get { return mButtonStyle; }

            set { mButtonStyle = value; this.Invalidate(); }

        }

 

        private int mCornerRadius = 3;

        /// <summary>

按钮边角的曲度

        /// </summary>

        [Category("Appearance"),

         DefaultValue(8)]

        public int CornerRadius

        {

            get { return mCornerRadius; }

            set { mCornerRadius = value; this.Invalidate(); }

        }

 

        private Color mHighlightColor = Color.Gray;

        /// <summary>

        高亮的颜色

        /// </summary>

        [Category("Appearance"),

         DefaultValue(typeof(Color), "White")]

        public Color HighlightColor

        {

            get { return mHighlightColor; }

            set { mHighlightColor = value; this.Invalidate(); }

        }

        private Color mButtonColor = Color.Black;

        /// <summary>

        /// The bottom color of the button that

        /// will be drawn over the base color.

        /// </summary>

        [Category("Appearance"),

         DefaultValue(typeof(Color), "Black")]

        public Color ButtonColor

        {

            get { return mButtonColor; }

            set { mButtonColor = value; this.Invalidate(); }

        }

 

        private Color mGlowColor = Color.FromArgb(141, 189, 255);

        /// <summary>

        /// 鼠标移上去之后显示的颜色

        /// </summary>

        [Category("Appearance"),

         DefaultValue(typeof(Color), "141,189,255")]

        public Color GlowColor

        {

            get { return mGlowColor; }

            set { mGlowColor = value; this.Invalidate(); }

        }

        private Image mBackImage;

        /// <summary>

背景图片

        /// </summary>

        [Category("Appearance"),

         DefaultValue(null)]

        public Image BackImage

        {

            get { return mBackImage; }

            set { mBackImage = value; this.Invalidate(); }

        }

 

        private static Color mBaseColor = Color.Black;

        /// <summary>

        /// The backing color that the rest of

        /// the button is drawn. For a glassier

        /// effect set this property to Transparent.

        /// </summary>

        [Category("Appearance"),

         DefaultValue(typeof(Color), "Black")]

        public Color BaseColor

        {

            get { return mBaseColor; }

            set { mBaseColor = value; this.Invalidate(); }

        }

        /// <summary>

        /// 按钮的形状

        /// </summary>

        /// <param name="r"></param>

        /// <param name="r1"></param>

        /// <param name="r2"></param>

        /// <param name="r3"></param>

        /// <param name="r4"></param>

        /// <returns></returns>

        private GraphicsPath RoundRect(RectangleF r, float r1, float r2, float r3, float r4)

        {

            float x = r.X, y = r.Y, w = r.Width, h = r.Height;

            GraphicsPath rr = new GraphicsPath();

            rr.AddBezier(x, y + r1, x, y, x + r1, y, x + r1, y);

            rr.AddLine(x + r1, y, x + w - r2, y);

            rr.AddBezier(x + w - r2, y, x + w, y, x + w, y + r2, x + w, y + r2);

            rr.AddLine(x + w, y + r2, x + w, y + h - r3);

            rr.AddBezier(x + w, y + h - r3, x + w, y + h, x + w - r3, y + h, x + w - r3, y + h);

            rr.AddLine(x + w - r3, y + h, x + r4, y + h);

            rr.AddBezier(x + r4, y + h, x, y + h, x, y + h - r4, x, y + h - r4);

            rr.AddLine(x, y + h - r4, x, y + r1);

            return rr;

        }

        /// <summary>

        /// 对齐方式

        /// </summary>

        /// <param name="textalign"></param>

        /// <returns></returns>

        private StringFormat StringFormatAlignment(ContentAlignment textalign)

        {

            StringFormat sf = new StringFormat();

            switch (textalign)

            {

                case ContentAlignment.TopLeft:

                case ContentAlignment.TopCenter:

                case ContentAlignment.TopRight:

                    sf.LineAlignment = StringAlignment.Near;

                    break;

                case ContentAlignment.MiddleLeft:

                case ContentAlignment.MiddleCenter:

                case ContentAlignment.MiddleRight:

                    sf.LineAlignment = StringAlignment.Center;

                    break;

                case ContentAlignment.BottomLeft:

                case ContentAlignment.BottomCenter:

                case ContentAlignment.BottomRight:

                    sf.LineAlignment = StringAlignment.Far;

                    break;

            }

            switch (textalign)

            {

                case ContentAlignment.TopLeft:

                case ContentAlignment.MiddleLeft:

                case ContentAlignment.BottomLeft:

                    sf.Alignment = StringAlignment.Near;

                    break;

                case ContentAlignment.TopCenter:

                case ContentAlignment.MiddleCenter:

                case ContentAlignment.BottomCenter:

                    sf.Alignment = StringAlignment.Center;

                    break;

                case ContentAlignment.TopRight:

                case ContentAlignment.MiddleRight:

                case ContentAlignment.BottomRight:

                    sf.Alignment = StringAlignment.Far;

                    break;

            }

            return sf;

        }

        /// <summary>

        /// 画出按钮的外框线条

        /// </summary>

        /// <param name="g">The graphics object used in the paint event.</param>

        private void DrawOuterStroke(Graphics g)

        {

            if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None) { return; }

            Rectangle r = this.ClientRectangle;

            r.Width -= 1; r.Height -= 1;

            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))  //圆角矩形

            {

                using (Pen p = new Pen(this.ButtonColor))

                {

                    g.DrawPath(p, rr);     //画出外框

                }

            }

        }

 

        /// <summary>

        /// 画出按钮的内框线条

        /// </summary>

        /// <param name="g">The graphics object used in the paint event.</param>

        private void DrawInnerStroke(Graphics g)

        {

            if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None) { return; }

            Rectangle r = this.ClientRectangle;

            r.X++; r.Y++;

            r.Width -= 3; r.Height -= 3;

            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))

            {

                using (Pen p = new Pen(this.HighlightColor))

                {

                    g.DrawPath(p, rr);

                }

            }

        }

 

        /// <summary>

        /// 画出按钮的背景

        /// </summary>

        /// <param name="g">The graphics object used in the paint event.</param>

        private void DrawBackground(Graphics g)

        {

            if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None) { return; }

            int alpha = (mButtonState == State.Pressed) ? 204 : 127;

            Rectangle r = this.ClientRectangle;

            r.Width--; r.Height--;

            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))

            {

                using (SolidBrush sb = new SolidBrush(this.BaseColor))

                {

                    g.FillPath(sb, rr);

                }

                if (this.BackImage != null) { g.DrawImage(this.BackImage, this.ClientRectangle); }

                g.ResetClip();

                using (SolidBrush sb = new SolidBrush(Color.FromArgb(alpha, this.ButtonColor)))

                {

                    g.FillPath(sb, rr);

                }

            }

        }

 

        /// <summary>

        /// 画出按钮的上半部分高光颜色

        /// </summary>

        /// <param name="g">The graphics object used in the paint event.</param>

        private void DrawHighlight(Graphics g)

        {

            if (this.ButtonStyle == Style.Flat && this.mButtonState == State.None) { return; }

            int alpha = (mButtonState == State.Pressed) ? 60 : 150;

            Rectangle rect = new Rectangle(0, 0, this.Width, this.Height / 2);

            using (GraphicsPath r = RoundRect(rect, CornerRadius, CornerRadius, 0, 0))

            {

                using (LinearGradientBrush lg = new LinearGradientBrush(r.GetBounds(),

                                            Color.FromArgb(alpha, this.HighlightColor),

                                            Color.FromArgb(alpha / 3, this.HighlightColor),

                                            LinearGradientMode.Vertical))

                {

                    g.FillPath(lg, r);

                }

            }

        }

 

        /// <summary>

        /// 当鼠标移上去的时候的炫光

        /// </summary>

        /// <param name="g">The graphics object used in the paint event.</param>

        private void DrawGlow(Graphics g)

        {

            if (this.mButtonState == State.Pressed) { return; }

            using (GraphicsPath glow = new GraphicsPath())

            {

                Rectangle r = this.ClientRectangle;

                //r.Width -= 3; r.Height -= 3;

                glow.AddPath(RoundRect(new Rectangle(r.Left + 1, r.Top + 1, r.Width - 3, r.Height - 3), CornerRadius, CornerRadius, CornerRadius, CornerRadius), true);

                using (GraphicsPath gp = RoundRect(new Rectangle(r.Left + 1, r.Top + 1, r.Width - 3, r.Height / 2 - 2), CornerRadius, CornerRadius, CornerRadius, CornerRadius))

                {

                    Color c = Color.FromArgb(mGlowAlpha, this.GlowColor);

                    Color c1 = Color.FromArgb(mGlowAlpha / 2 + 50, Color.White);

                    using (SolidBrush sb = new SolidBrush(c))

                    {

                        using (SolidBrush sb1 = new SolidBrush(c1))

                        {

                            g.FillPath(sb, glow);

                            g.FillPath(sb1, gp);

                        }

                    }

                }

            }

            g.ResetClip();

        }

        /// <summary>

        /// 显示按钮的文本

        /// </summary>

        /// <param name="g">The graphics object used in the paint event.</param>

        private void DrawText(Graphics g)

        {

            StringFormat sf = StringFormatAlignment(this.TextAlign);

            Rectangle r = new Rectangle(8, 8, this.Width - 17, this.Height - 17);

            g.DrawString(this.ButtonText, this.Font, new SolidBrush(this.ForeColor), r, sf);

        }

        /// <summary>

        /// 画出按钮上的图标

        /// </summary>

        /// <param name="g"></param>

        private void DrawIcon(Graphics g)

        {

            if (this.UT == UseTo.Close)

            {

                //关闭图片

            }

            else if (this.UT == UseTo.Min)

            {

                //最小化的图片

            }

        }

        private void VistaButton_Paint(object sender, PaintEventArgs e)

        {

            Graphics g = e.Graphics;

            g.SmoothingMode = SmoothingMode.AntiAlias;

            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            DrawBackground(g);

            DrawHighlight(g);

            DrawGlow(g);

            DrawIcon(g);

            DrawInnerStroke(g);

        }

        private void VistaButton_Resize(object sender, EventArgs e)

        {

            Rectangle r = this.ClientRectangle;

            r.X -= 1; r.Y -= 1;

            r.Width += 2; r.Height += 2;

            using (GraphicsPath rr = RoundRect(r, CornerRadius, CornerRadius, CornerRadius, CornerRadius))

            {

                this.Region = new Region(rr);

            }

        }

        private void VistaButton_MouseEnter(object sender, EventArgs e)

        {

            mButtonState = State.Hover;

            mFadeOut.Stop();

            mFadeIn.Start();

        }

        private void VistaButton_MouseLeave(object sender, EventArgs e)

        {

            mButtonState = State.None;

            if (this.mButtonStyle == Style.Flat) { mGlowAlpha = 0; }

            mFadeIn.Stop();

            mFadeOut.Start();

        }

 

        private void VistaButton_MouseDown(object sender, MouseEventArgs e)

        {

            if (e.Button == MouseButtons.Left)

            {

                mButtonState = State.Pressed;

                if (this.mButtonStyle != Style.Flat) { mGlowAlpha = 255; }

                mFadeIn.Stop();

                mFadeOut.Stop();

                this.Invalidate();

            }

        }

 

        private void mFadeIn_Tick(object sender, EventArgs e)

        {

            if (this.ButtonStyle == Style.Flat) { mGlowAlpha = 0; }

            if (mGlowAlpha + 30 >= 255)

            {

                mGlowAlpha = 255;

                mFadeIn.Stop();

            }

            else

            {

                mGlowAlpha += 30;

            }

            this.Invalidate();

        }

 

        private void mFadeOut_Tick(object sender, EventArgs e)

        {

            if (this.ButtonStyle == Style.Flat) { mGlowAlpha = 0; }

            if (mGlowAlpha - 30 <= 0)

            {

                mGlowAlpha = 0;

                mFadeOut.Stop();

            }

            else

            {

                mGlowAlpha -= 30;

            }

            this.Invalidate();

        }

 

        private void VistaButton_KeyDown(object sender, KeyEventArgs e)

        {

            if (e.KeyCode == Keys.Space)

            {

                MouseEventArgs m = new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0);

                VistaButton_MouseDown(sender, m);

            }

        }

 

        private void VistaButton_KeyUp(object sender, KeyEventArgs e)

        {

            if (e.KeyCode == Keys.Space)

            {

                MouseEventArgs m = new MouseEventArgs(MouseButtons.Left, 0, 0, 0, 0);

                calledbykey = true;

                VistaButton_MouseUp(sender, m);

            }

        }

 

        private void VistaButton_MouseUp(object sender, MouseEventArgs e)

        {

            if (e.Button == MouseButtons.Left)

            {

                mButtonState = State.Hover;

                mFadeIn.Stop();

                mFadeOut.Stop();

                this.Invalidate();

                if (calledbykey == true) { this.OnClick(EventArgs.Empty); calledbykey = false; }

            }

        }

    }

}

 

原文地址:https://www.cnblogs.com/saper/p/1389620.html