1. 程式人生 > >C# GDI進行Button重繪

C# GDI進行Button重繪

public partial class ButtonEx : Button
{
    public ButtonEx() {
        //首先開啟雙緩衝,防止閃爍
        //雙緩衝的一大堆設定 具體引數含義參照msdn的ControlStyles列舉值
        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.ResizeRedraw, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        this.BackColor = Color.Transparent;
    }
    //用來標示是否滑鼠正在懸浮在按鈕上  true:懸浮在按鈕上 false:滑鼠離開了按鈕
    private bool m_bMouseHover;
    //用來標示是否滑鼠點選了按鈕  true:按下了按鈕 false:鬆開了按鈕
    private bool m_bMouseDown;
 
    //過載滑鼠懸浮的事件
    protected override void OnMouseEnter(EventArgs e) {
        //當滑鼠進入控制元件時,標示變數為進入了控制元件
        m_bMouseHover = true;
        //重新整理面板觸發OnPaint重繪
        this.Invalidate();
        base.OnMouseEnter(e);
    }
 
    //過載滑鼠離開的事件
    protected override void OnMouseLeave(EventArgs e) {
        //當滑鼠離開控制元件時,標示變數為離開了控制元件
        m_bMouseHover = false;
        //重新整理面板觸發OnPaint重繪
        this.Invalidate();
        base.OnMouseLeave(e);
    }
 
    //過載滑鼠按下的事件
    protected override void OnMouseDown(MouseEventArgs mevent) {
        //當滑鼠按下控制元件時,標示變數為按下了控制元件
        m_bMouseDown = true;
        //重新整理面板觸發OnPaint重繪
        this.Invalidate();
        base.OnMouseDown(mevent);
    }
 
    //過載滑鼠鬆開的事件
    protected override void OnMouseUp(MouseEventArgs mevent) {
        //當滑鼠鬆開時,標示變數為按下並鬆開了控制元件
        m_bMouseDown = false;
        //重新整理面板觸發OnPaint重繪
        this.Invalidate();
        base.OnMouseUp(mevent);
    }
 
    //過載繪畫事件
    protected override void OnPaint(PaintEventArgs pevent) {
        base.OnPaint(pevent);
        //因為上面呼叫了base會繪製原生控制元件 重刷一下背景清掉原生繪製 不然自己繪製的是重疊在原生繪製上
        base.OnPaintBackground(pevent);
        //得到繪畫控制代碼
        Graphics g = pevent.Graphics;
        //定義字型格式
        StringFormat sf = new StringFormat();
        sf.Alignment = StringAlignment.Center;
        sf.LineAlignment = StringAlignment.Center;
        //處理熱鍵 當Alt點下時
        sf.HotkeyPrefix = this.ShowKeyboardCues ? HotkeyPrefix.Show : HotkeyPrefix.Hide;
        //判斷使用什麼資源圖
        Bitmap bmpDraw = Properties.Resources.QBtn_Normal;
        //如果禁用了,則使用禁用時的樣式圖片繪製,否則呼叫其他滿足條件的樣式圖片繪製
        if (!this.Enabled) bmpDraw = Properties.Resources.Qbtn_Gray;
        else if (m_bMouseDown) bmpDraw = Properties.Resources.QBtn_Down;
        else if (m_bMouseHover) bmpDraw = Properties.Resources.QBtn_High;
        else if (this.Focused) bmpDraw = Properties.Resources.QBtn_Focus;
        //繪製背景(若不知道這句啥意思 參照九宮切圖裡面的程式碼)
        RenderHelper.RenderBackground(g, bmpDraw, this.ClientRectangle);
        //如果禁用了
        if (!this.Enabled) {
            //則繪製雙重陰影文字
            g.DrawString(this.Text, this.Font, Brushes.White, this.ClientRectangle, sf);
            g.TranslateTransform(-1, -1);//左上移動一個單位座標系
            g.DrawString(this.Text, this.Font, Brushes.DarkGray, this.ClientRectangle, sf);
            g.ResetTransform();
            return;
        }
        //否則,預設繪製正常字型
        using (SolidBrush sb = new SolidBrush(this.ForeColor)) {
            g.DrawString(this.Text, this.Font, sb, this.ClientRectangle, sf);
        }
    }
}