mfc送水视频下载:如何设置自定义按钮的样式

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 08:32:04
MFC编程中系统提供的一些样式,一般都比较难看,所以有的时候为了美观,需要自己定义些样式,现那Button按钮来举例.首先新建一名为XPButton的MFC Application的对话框应用程序,在Class View中新增加一个自定义样式的MFC Class类,类名为CNewButton,基类为CButton.NewButton.h的代码如下:class CNewButton : public CButton{    public:          CNewButton();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;     //按钮为当前焦点所在时该值为truepublic:protected:     virtual voidPreSubclassWindow();     public:     virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);     virtual void DoGradientFill(CDC *pDC, CRect* rect);     virtual void DrawInsideBorder(CDC *pDC, CRect* rect);     virtual ~CNewButton();protected:     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()};NewButton.cpp的代码如下:#include "stdafx.h"#include "NewButton.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCNewButton::CNewButton() //构造函数{     m_BoundryPen.CreatePen(PS_INSIDEFRAME | PS_SOLID, 1, RGB(0, 0, 0));//按钮的外边框画笔     m_InsideBoundryPenLeft.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(61, 97, 88));    m_InsideBoundryPenRight.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(61, 137, 106));     m_InsideBoundryPenTop.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(102, 167, 114));    m_InsideBoundryPenBottom.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(102, 167, 114));     //按钮的背景色     m_FillActive.CreateSolidBrush(RGB(223, 222, 236));     m_FillInactive.CreateSolidBrush(RGB(222, 223, 236));     m_InsideBoundryPenLeftSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(139, 189, 157));     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;}CNewButton::~CNewButton(){     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(CNewButton, CButton)     ON_WM_MOUSEMOVE()     ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)     ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)END_MESSAGE_MAP() //添加Owner Draw属性void CNewButton::PreSubclassWindow(){     CButton::PreSubclassWindow();     ModifyStyle(0, BS_OWNERDRAW);}void CNewButton::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 = 1;         m_bTracking = _TrackMouseEvent(&tme);     }     CButton::OnMouseMove(nFlags, point);}LRESULT CNewButton::OnMouseLeave(WPARAM wParam, LPARAM lParam){     m_bOver = FALSE;     m_bTracking = FALSE;     InvalidateRect(NULL, FALSE);     return 0;}LRESULT CNewButton::OnMouseHover(WPARAM wParam, LPARAM lParam){     m_bOver = TRUE;     InvalidateRect(NULL);     return 0;}void CNewButton::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 CNewButton::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 CNewButton::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.设置某个按钮为上面所定义的样式,只需右键点击该按钮,添加变量,变量的类型CNewButton,变量名为m_Button.编译运行,就可以看到自己定义的按钮.