VC中对按钮控件的修改[转载]

VC中对按钮控件的修改

在VC6.0环境下,通过向导设置建立基于MFC AppWizard[exe]  名称为MyClassBTNdemo的project (图1),基于Dialog(图2)。项目建立好了以后,左侧的导航栏点击FILEVIEW,展开的列表文件(图3),通过文件File->new添加ClassBTN.cpp和ClassBTN.h文件。我们的主要工作都是在这两个文件夹中设置的。

1、在 ClassBTN.h文件中添加代码:

 

#if !defined(AFX_CLASSBTN_H__44CD5B2A_756E_4939_9261_E0034E0F2DEF__INCLUDED_)

#define AFX_CLASSBTN_H__44CD5B2A_756E_4939_9261_E0034E0F2DEF__INCLUDED_

 

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// ClassBTN.h : header file

//

 

/

// CClassBTN window

 

class CClassBTN : public CButton

{

// Construction

public:

       CClassBTN();

 

       // Attributes

protected:

       //按钮的外边框

       CPen m_BoundryPen;

      

       //鼠标指针置于按钮之上时按钮的内边框

       CPen m_InsideBoundryPenLeft;

       CPen m_InsideBoundryPenRight;

       CPen m_InsideBoundryPenTop;

       CPen m_InsideBoundryPenBottom;

      

       //按钮获得焦点时按钮的内边框

       CPen m_InsideBoundryPenLeftSel;

       CPen m_InsideBoundryPenRightSel;

       CPen m_InsideBoundryPenTopSel;

       CPen m_InsideBoundryPenBottomSel;

      

       //按钮的底色,包括有效和无效两种状态

       CBrush m_FillActive;

       CBrush m_FillInactive;

      

       //按钮的状态

       BOOL m_bOver;    //鼠标位于按钮之上时该值为true,反之为flase

       BOOL m_bTracking;     //在鼠标按下没有释放时该值为true

       BOOL m_bSelected;      //按钮被按下是该值为true

       BOOL m_bFocus;  //按钮为当前焦点所在时该值为true

 

// Operations

public:

 

// Overrides

       // ClassWizard generated virtual function overrides

       //{{AFX_VIRTUAL(CClassBTN)

       protected:

       virtual void PreSubclassWindow();

       //}}AFX_VIRTUAL

 

// Implementation

public:

       virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

       virtual void DoGradientFill(CDC *pDC, CRect* rect);

       virtual void DrawInsideBorder(CDC *pDC, CRect* rect);

       virtual ~CClassBTN();

 

       // Generated message map functions

protected:

       //{{AFX_MSG(CClassBTN)

       afx_msg void OnMouseMove(UINT nFlags, CPoint point);

       afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);

       afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);

      

       //}}AFX_MSG

 

       DECLARE_MESSAGE_MAP()

};

 

/

 

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

 

#endif // !defined(AFX_CLASSBTN_H__44CD5B2A_756E_4939_9261_E0034E0F2DEF__INCLUDED_)

///

2、在文件ClassBTN.cpp中添加下列代码

// ClassBTN.cpp : implementation file

//

 

#include "stdafx.h"

#include "ClassBTN.h"

 

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

 

/

// CClassBTN

 

CClassBTN::CClassBTN()

 

{

       m_BoundryPen.CreatePen(PS_INSIDEFRAME | PS_SOLID, 1, RGB(0, 0, 0));

       m_InsideBoundryPenLeft.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(250, 196, 88));

       m_InsideBoundryPenRight.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(251, 202, 106));

       m_InsideBoundryPenTop.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(252, 210, 121));

       m_InsideBoundryPenBottom.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(229, 151, 0));

      

       m_FillActive.CreateSolidBrush(RGB(223, 222, 236));

       m_FillInactive.CreateSolidBrush(RGB(222, 223, 236));

      

       m_InsideBoundryPenLeftSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(153, 198, 252));

       m_InsideBoundryPenTopSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(162, 201, 255));

       m_InsideBoundryPenRightSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(162, 189, 252));

       m_InsideBoundryPenBottomSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(162, 201, 255));

      

       m_bOver = m_bSelected = m_bTracking = m_bFocus = FALSE;

      

}

CClassBTN::~CClassBTN()

{

       m_BoundryPen.DeleteObject();

       m_InsideBoundryPenLeft.DeleteObject();

       m_InsideBoundryPenRight.DeleteObject();

       m_InsideBoundryPenTop.DeleteObject();

       m_InsideBoundryPenBottom.DeleteObject();

      

       m_FillActive.DeleteObject();

       m_FillInactive.DeleteObject();

      

       m_InsideBoundryPenLeftSel.DeleteObject();

       m_InsideBoundryPenTopSel.DeleteObject();

       m_InsideBoundryPenRightSel.DeleteObject();

       m_InsideBoundryPenBottomSel.DeleteObject();

      

}

 

 

BEGIN_MESSAGE_MAP(CClassBTN, CButton)

       //{{AFX_MSG_MAP(CClassBTN)

       ON_WM_MOUSEMOVE()

       ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)

       ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)

       //}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

/

// CClassBTN message handlers

 

//添加Owner Draw属性

void CClassBTN::PreSubclassWindow()

{

       // TODO: Add your specialized code here and/or call the base class

      

       CButton::PreSubclassWindow();

       ModifyStyle(0, BS_OWNERDRAW);

}

 

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

{

       // TODO: Add your message handler code here and/or call default

       if (!m_bTracking)

       {

              TRACKMOUSEEVENT tme;

              tme.cbSize = sizeof(tme);

              tme.hwndTrack = m_hWnd;

              tme.dwFlags = TME_LEAVE | TME_HOVER;

              tme.dwHoverTime = 1;

              m_bTracking = _TrackMouseEvent(&tme);

       }

      

       CButton::OnMouseMove(nFlags, point);

}

 

 

LRESULT CClassBTN::OnMouseLeave(WPARAM wParam, LPARAM lParam)

{

       m_bOver = FALSE;

       m_bTracking = FALSE;

       InvalidateRect(NULL, FALSE);

       return 0;

}

 

LRESULT CClassBTN::OnMouseHover(WPARAM wParam, LPARAM lParam)

{

       m_bOver = TRUE;

       InvalidateRect(NULL);

       return 0;

}

 

 

void CClassBTN::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

       //从lpDrawItemStruct获取控件的相关信息

       CRect rect =  lpDrawItemStruct->rcItem;

       CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);

       int nSaveDC=pDC->SaveDC();

       UINT state = lpDrawItemStruct->itemState;

       POINT pt ;

       TCHAR strText[MAX_PATH + 1];

       ::GetWindowText(m_hWnd, strText, MAX_PATH);

      

       //画按钮的外边框,它是一个半径为5的圆角矩形

       pt.x = 5;

       pt.y = 5;

       CPen* hOldPen = pDC->SelectObject(&m_BoundryPen);

       pDC->RoundRect(&rect, pt);

      

       //获取按钮的状态

       if (state & ODS_FOCUS)

       {

              m_bFocus = TRUE;

              m_bSelected = TRUE;

       }

       else

       {

              m_bFocus = FALSE;

              m_bSelected = FALSE;

       }

      

      

       if (state & ODS_SELECTED || state & ODS_DEFAULT)

       {

              m_bFocus = TRUE;

       }

 

      

       pDC->SelectObject(hOldPen);

      

       rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));

      

       //根据按钮的状态填充按钮的底色

       CBrush* pOldBrush;

       if (m_bOver)

       {

              pOldBrush = pDC->SelectObject(&m_FillActive);

              DoGradientFill(pDC, &rect);

       }

       else

       {

              pOldBrush = pDC->SelectObject(&m_FillInactive);

              DoGradientFill(pDC, &rect);

       }

      

       //根据按钮的状态绘制内边框

       if (m_bOver || m_bSelected)

              DrawInsideBorder(pDC, &rect);

                           

       pDC->SelectObject(pOldBrush);

      

       //显示按钮的文本

       if (strText!=NULL)

       {

              CFont* hFont = GetFont();

              CFont* hOldFont = pDC->SelectObject(hFont);

              CSize szExtent = pDC->GetTextExtent(strText, lstrlen(strText));

              CPoint pt( rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);

              if (state & ODS_SELECTED)

                     pt.Offset(1, 1);

              int nMode = pDC->SetBkMode(TRANSPARENT);

              if (state & ODS_DISABLED)

                     pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);

              else

                     pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);

              pDC->SelectObject(hOldFont);

              pDC->SetBkMode(nMode);

       }

      

      

       pDC->RestoreDC(nSaveDC);

}

 

//绘制按钮的底色

void CClassBTN::DoGradientFill(CDC *pDC, CRect* rect)

{

       CBrush brBk[64];

       int nWidth = rect->Width();  

       int nHeight = rect->Height();

       CRect rct;

      

       for (int i = 0; i < 64; i ++)

       {

              if (m_bOver)

              {

                 if (m_bFocus)

              brBk[i].CreateSolidBrush(RGB(255 - (i / 4), 255 - (i / 4), 255 - (i / 3)));

                 else

              brBk[i].CreateSolidBrush(RGB(255 - (i / 4), 255 - (i / 4), 255 - (i / 5)));

              }

              else

              {

                     if (m_bFocus)

              brBk[i].CreateSolidBrush(RGB(255 - (i / 3), 255 - (i / 3), 255 - (i / 4)));

                     else

              brBk[i].CreateSolidBrush(RGB(255 - (i / 3), 255 - (i / 3), 255 - (i / 5)));

              }

       } 

       for (i = rect->top; i <= nHeight + 2; i ++)

       {             

              rct.SetRect(rect->left, i, nWidth + 2, i + 1);

              pDC->FillRect(&rct, &brBk[((i * 63) / nHeight)]);

       }

              for (i = 0; i < 64; i ++)

              brBk[i].DeleteObject();

}

//绘制按钮的内边框

void CClassBTN::DrawInsideBorder(CDC *pDC, CRect* rect)

{

       CPen *pLeft, *pRight, *pTop, *pBottom;

      

       if (m_bSelected && !m_bOver)

       {

              pLeft = & m_InsideBoundryPenLeftSel;

              pRight = &m_InsideBoundryPenRightSel;

              pTop = &m_InsideBoundryPenTopSel;

              pBottom = &m_InsideBoundryPenBottomSel;

       }

       else

       {

              pLeft = &m_InsideBoundryPenLeft;

              pRight = &m_InsideBoundryPenRight;

              pTop = &m_InsideBoundryPenTop;

              pBottom = &m_InsideBoundryPenBottom;

       }

       CPoint oldPoint = pDC->MoveTo(rect->left, rect->bottom - 1);

       CPen* pOldPen = pDC->SelectObject(pLeft);

       pDC->LineTo(rect->left, rect->top + 1);

       pDC->SelectObject(pRight);

       pDC->MoveTo(rect->right - 1, rect->bottom - 1);

       pDC->LineTo(rect->right - 1, rect->top);

       pDC->SelectObject(pTop);

       pDC->MoveTo(rect->left - 1, rect->top);

       pDC->LineTo(rect->right - 1, rect->top);

       pDC->SelectObject(pBottom);

       pDC->MoveTo(rect->left, rect->bottom);

       pDC->LineTo(rect->right - 1, rect->bottom);

       pDC->SelectObject(pOldPen);

       pDC->MoveTo(oldPoint);

       if (m_bSelected && !m_bOver)

              DrawFocusRect(pDC->m_hDC,rect);

}

3、/*添加头文件*/

在MyClassBTNdemo.h中添加头文件

#include “ClassBTN.h”(如图4)

4、在ResurseView 下添加相应的按钮控件如图(5)

 

5、添加变量,按钮真正的达到效果

 首先在MyClassBTNdemo中添加(图6)

 

       CClassBTN     m_btnOK;              /*默认按钮 确定*/

       CClassBTN     m_btnCancel;           /*默认按钮 取消*/

       CClassBTN     m_btnmakesure;         /*新加按钮 Button1*/

6、添加相应的对话框消息机制

在MyClassBTNdemo.cpp中CAboutDlg::DoDataExchange(CDataExchange* pDX)成员函数内添加代码(图7)

       DDX_Control(pDX, IDOK, m_btnOK);

       DDX_Control(pDX, IDCANCEL, m_btnCancel);

       DDX_Control(pDX, IDC_BUTTON4, m_btnmakesure);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值