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

    最终效果图:

  • 相关阅读:
    组件映射
    联合主键关联
    一对一单向双向主键关联
    7函数
    forEach与map
    3运算符与表达式
    作用域声明提升
    php程序设计 1,2章节
    angularJs(3)过滤器
    angularJs(1)指令篇
  • 原文地址:https://www.cnblogs.com/bemawen/p/3090972.html
Copyright © 2011-2022 走看看