zoukankan      html  css  js  c++  java
  • 利用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; }

                }

            }

        }

    }

     

  • 相关阅读:
    String对象的属性和方法
    Math对象的属性和方法
    对象Date的方法
    HTML5和CSS3阶段,我是如何学习的?
    移动端项目开发心得
    关于元素隐藏/显示的各种方法
    啊哈算法(一)
    项目心得。
    CSS篇之DIV+CSS布局
    CSS篇之动画(2)
  • 原文地址:https://www.cnblogs.com/saper/p/1389620.html
Copyright © 2011-2022 走看看