MFC按鈕美化實現Win8默認按鈕效果


         由於MFC的按鈕樣式過於古老,不做美化的話開發出來的軟件跟Windows98上的軟件一樣,所以有必要對MFC的CButton類進行擴展生繪。

         先說下思路,要改CButton的外觀的話只要對DrawItem虛函數進行重寫就可以了。通過itemState可以判斷出按鈕的狀態,比如焦點、禁用、默認等等,鼠標進入和移出需要自己響應MouseMove消息。

具體實現代碼:

MyButton.h:

#pragma once

#include "afxwin.h"

 

class CMyButton : public CButton

{

 //DECLARE_DYNAMIC(CMyButton)

private:

         bool _isCustom;

         COLORREF upBorderColor,downBorderColor,focusBorderColor,hoverBorderColor,diableBorderColor; //定義彈起、銨下、焦點、鼠標進入、禁用的邊框顏色

COLORREF disableBgColor;//定義禁用的背景顏色

int hoverBgColorR0,hoverBgColorG0,hoverBgColorB0,hoverBgColorR1,hoverBgColorG1,hoverBgColorB1;//分別定義鼠標進入的上邊RGB和下邊RGB顏色(實現漸變)

int upBgColorR0,upBgColorG0,upBgColorB0,upBgColorR1,upBgColorG1,upBgColorB1;

int downBgColorR0,downBgColorG0,downBgColorB0,downBgColorR1,downBgColorG1,downBgColorB1;//同上,鼠標銨下顏色

public:

 CMyButton();

 virtual ~CMyButton();

 void SetDownColor(COLORREF color); //設置Button Down的背景顏色

 void SetUpColor(COLORREF color);//設置彈起顏色

 void SetFont(CFont* font);//設置字體

 void SetFontColor(COLORREF color);//設置字體顏色

 CWnd* cWndParent;

 BOOL Attach(int nID, CWnd* pParent);//根據資源ID創建自定義按鈕

protected:

    //必需重載的函數

    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);//重案繪制函數

public:

         WNDPROC OldWndProc;

         CtoolTipCtrl m_Mytip;

 BOOL m_bTracking;

         LRESULT   CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);

 //三種顏色分別為文字,Button Down的背景顏色,Button Up的背景顏色

 COLORREF m_TextColor, m_DownColor, m_UpColor,m_TempColor;

protected:

         // Generated message map functions

         //{{AFX_MSG(CMyButton)

         //}}AFX_MSG

         afx_msg void OnMouseMove(UINT nFlags, CPoint point);

         afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);//鼠標離開事件

         afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);//鼠標進入事件

         DECLARE_MESSAGE_MAP()

};

 

MyButton.cpp:

#include "StdAfx.h"

#include "MyButton.h"

 

BEGIN_MESSAGE_MAP(CMyButton, CButton)

 //{{AFX_MSG_MAP(CMyButton)

 ON_WM_MOUSEMOVE()

 ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)//鼠標離開

 ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)//鼠標懸掛

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

CMyButton::CMyButton(void)

{

          m_TempColor=m_TextColor=m_DownColor = m_UpColor = RGB(0,0,0);

          m_Mytip.Create(this);

          m_bTracking=false;

         _isCustom=false;

        

         upBorderColor=RGB(172,172,172);

         upBgColorR0=upBgColorG0=upBgColorB0=240;

         upBgColorR1=upBgColorG1=upBgColorB1=229;

 

         hoverBorderColor=RGB(126,180,234);

         hoverBgColorR0=236;

         hoverBgColorG0=244;

         hoverBgColorB0=252;

         hoverBgColorR1=220;

         hoverBgColorG1=236;

         hoverBgColorB1=252;

 

         downBorderColor=RGB(86,157,229);

         downBgColorR0=218;

         downBgColorG0=232;

         downBgColorB0=252;

         downBgColorR1=196;

         downBgColorG1=224;

         downBgColorB1=252;

 

         focusBorderColor=RGB(51,153,255);

 

         diableBorderColor=RGB(217,217,217);

         disableBgColor=RGB(239,239,239);

}

 

CMyButton::~CMyButton(void){

}

 

BOOL CMyButton::Attach(int nID, CWnd* pParent){

         cWndParent=pParent->GetDlgItem(nID);

         cWndParent->ModifyStyle(0,BS_OWNERDRAW,0);

         if (!SubclassDlgItem(nID, pParent))

                   return FALSE;

         return TRUE;

}

 

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){

 // TODO: Add your code to draw the specified item

         CDC dc;

         dc.Attach(lpDrawItemStruct->hDC);//得到繪制的設備環境CDC

         VERIFY(lpDrawItemStruct->CtlType==ODT_BUTTON);

         const int bufSize = 512;

         TCHAR buffer[bufSize];

         GetWindowText(buffer, bufSize);//獲取按鈕上的文字

int size=strlen(buffer);   //得到文字長度

SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);   //設置背景透明

         if (lpDrawItemStruct->itemState &ODS_SELECTED){  //當按下按鈕時的處理

                   CRect rect;

                   GetClientRect(&rect);//獲取按鈕區域

                   for(int i=0;i<rect.Height();i++){//處理漸變,如果是垂直方向則rect.Height(),下同 

                            int r,g,b;

                            r = downBgColorR0 + (i * (downBgColorR1-downBgColorR0) / rect.Height()); 

                            g = downBgColorG0 + (i * (downBgColorG1-downBgColorG0) / rect.Height()); 

                            b = downBgColorB0 + (i * (downBgColorB1-downBgColorB0) / rect.Height()); 

                            dc.FillSolidRect(0,i,rect.Width(),1,RGB(r,g,b));//填充一條直線

}

         DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);//繪制文字

SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);//設置背景透明

                  CBrush brush1(downBorderColor);//邊框顏色

                 dc.SetTextColor(RGB(0,0,0));//設置文字顏色

                 dc.FrameRect(&(lpDrawItemStruct->rcItem),&brush1);//

         }

         else if(lpDrawItemStruct->itemState &ODS_FOCUS||lpDrawItemStruct->itemState &ODS_CHECKED){//獲得焦點處理,同上

                   CRect rect;

                   GetClientRect(&rect); 

                   for(int i=0;i<rect.Height();i++){    //如果是垂直方向則rect.Height(),下同 

                            int r,g,b; 

                            r = upBgColorR0 + (i * (upBgColorR1-upBgColorR0) / rect.Height()); 

                            g = upBgColorG0 + (i * (upBgColorG1-upBgColorG0) / rect.Height()); 

                            b = upBgColorB0 + (i * (upBgColorB1-upBgColorB0) / rect.Height()); 

                            dc.FillSolidRect(0,i,rect.Width(),1,RGB(r,g,b)););

}                           DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);                           

                   DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);

                   SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);

                   CBrush brush1(focusBorderColor);//邊框顏色

                   dc.SetTextColor(RGB(0,0,0));//設置文字顏色

                   dc.FrameRect(&lpDrawItemStruct->rcItem,&brush1);//

         }

         else if(lpDrawItemStruct->itemState &ODS_DISABLED){//禁用處理,同上

                   CBrush brush(disableBgColor);//背景顏色

                   dc.FillRect(&(lpDrawItemStruct->rcItem),&brush);

                   dc.SetTextColor(RGB(131,131,131));//設置文字顏色

         DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);

                   DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);

                   SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);

                   CBrush brush1(diableBorderColor);//邊框顏色

                   dc.FrameRect(&lpDrawItemStruct->rcItem,&brush1);//

         }

         else{//當按鈕不操作或者彈起處理

                  CRect rect; 

                   GetClientRect(&rect); 

                   for(int i=0;i<rect.Height();i++){    //如果是垂直方向則rect.Height(),下同 

                            int r,g,b; 

                            r = upBgColorR0 + (i * (upBgColorR1-upBgColorR0) / rect.Height()); 

                            g = upBgColorG0 + (i * (upBgColorG1-upBgColorG0) / rect.Height()); 

                            b = upBgColorB0 + (i * (upBgColorB1-upBgColorB0) / rect.Height()); 

                            dc.FillSolidRect(0,i,rect.Width(),1,RGB(r,g,b));

                  }

                    DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);   

                   SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);

                   CBrush brush1(upBorderColor);//邊框顏色

                   dc.SetTextColor(RGB(0,0,0));//設置文字顏色

                   dc.FrameRect(&lpDrawItemStruct->rcItem,&brush1);//

         }

         dc.Detach();

}

 

void CMyButton::OnMouseMove(UINT nFlags, CPoint point)

{

         if (!m_bTracking)

          {

                    TRACKMOUSEEVENT tme;

                    tme.cbSize = sizeof(tme);

                    tme.hwndTrack = m_hWnd;

                    tme.dwFlags = TME_LEAVE | TME_HOVER;

                    tme.dwHoverTime = 10;

                    m_bTracking = _TrackMouseEvent(&tme);

          }

}

LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam){

         m_bTracking=false;

         if(!_isCustom){                  

                   upBorderColor=RGB(172,172,172);;

                   upBgColorR0=upBgColorG0=upBgColorB0=240;

                   upBgColorR1=upBgColorG1=upBgColorB1=229;

         }

         else{

                   m_UpColor=m_TempColor;

                   //m_TextColor=RGB(255,255,0);

         }

         Invalidate(); //重繪按鈕

         return 0;

}

 

LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam){

         if(!_isCustom){

                   upBorderColor=hoverBorderColor;

         //      upBgColor=hoverBgColor;               

                   upBgColorR0=hoverBgColorR0;

                   upBgColorG0=hoverBgColorG0;

                   upBgColorB0=hoverBgColorB0;

                   upBgColorR1=hoverBgColorR1;

                   upBgColorG1=hoverBgColorG1;

                   upBgColorB1=hoverBgColorB1;

         }

         else{

                   //m_TextColor=RGB(255,0,255);

                   m_UpColor=m_DownColor;

         }

         Invalidate(); //重繪按鈕

         return 0;

}

 

使用:

         在窗體的頭文件中添加引用:

                   #include "MyButton.h"

         並創建CmyButton對象:

CMyButton myBtnSubmit;

         在窗體的OnInitDialog()事件中添加如下代碼

                   myBtnSubmit.Attach(btnSubmit,this);

最終效果圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM