一个在MFC下使用的按钮美化类XPButton

//  XPButton.h

  1. /* usage:
  2. 1、
  3. private:
  4.     CXPButton m_cXPButton_IDC_BUTTON1;
  5. 2、
  6. void CXXXDlg::DoDataExchange(CDataExchange* pDX)
  7. {
  8.     CDialog::DoDataExchange(pDX);
  9.     DDX_Control(pDX, IDC_BUTTON1, m_cXPButton_IDC_BUTTON1);
  10. }
  11. */ 
  12.  
  13. #pragma once 
  14.  
  15. #include <afxwin.h> 
  16.  
  17. class CXPButton : public CButton 
  18. public
  19.     CXPButton(); 
  20.     virtual ~CXPButton(); 
  21.  
  22. public
  23.     // CWnd 
  24.     virtual void PreSubclassWindow(); 
  25.  
  26.     // CButton 
  27.     virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); 
  28.  
  29. protected
  30.     afx_msg void OnMouseMove(UINT nFlags, CPoint point); 
  31.     afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam); 
  32.     afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam); 
  33.     DECLARE_MESSAGE_MAP() 
  34.  
  35. protected
  36.     CPen m_BoundryPen; 
  37.  
  38.     CPen m_InsideBoundryPenLeft; 
  39.     CPen m_InsideBoundryPenRight; 
  40.     CPen m_InsideBoundryPenTop; 
  41.     CPen m_InsideBoundryPenBottom; 
  42.  
  43.     CPen m_InsideBoundryPenLeftSel; 
  44.     CPen m_InsideBoundryPenRightSel; 
  45.     CPen m_InsideBoundryPenTopSel; 
  46.     CPen m_InsideBoundryPenBottomSel; 
  47.  
  48.     BOOL m_bOver; 
  49.     BOOL m_bTracking; 
  50.     BOOL m_bSelected; 
  51.     BOOL m_bFocus; 
  52.  
  53. protected
  54.     void DrawInsideBorder(CDC* pDC, CRect* rect); 
  55.     void DrawText(CDC* pDC, const CRect& rect, UINT state, LPCSTR strText); 
  56. }; 
/* usage:

1、
private:
    CXPButton m_cXPButton_IDC_BUTTON1;

2、
void CXXXDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_BUTTON1, m_cXPButton_IDC_BUTTON1);
}

*/

#pragma once

#include <afxwin.h>

class CXPButton : public CButton
{
public:
    CXPButton();
    virtual ~CXPButton();

public:
    // CWnd
    virtual void PreSubclassWindow();

    // CButton
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

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()

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;

    BOOL m_bOver;
    BOOL m_bTracking;
    BOOL m_bSelected;
    BOOL m_bFocus;

protected:
    void DrawInsideBorder(CDC* pDC, CRect* rect);
    void DrawText(CDC* pDC, const CRect& rect, UINT state, LPCSTR strText);
};


// XPButton.cpp

  1. #include "stdafx.h" 
  2. #include "XPButton.h" 
  3.  
  4. CXPButton::CXPButton() 
  5. : m_bOver(FALSE) 
  6. , m_bTracking(FALSE) 
  7. , m_bSelected(FALSE) 
  8. , m_bFocus(FALSE) 
  9.     m_BoundryPen.CreatePen               (PS_INSIDEFRAME | PS_SOLID, 1, RGB( 55, 98,  6)); 
  10.     m_InsideBoundryPenLeft.CreatePen     (PS_INSIDEFRAME | PS_SOLID, 3, RGB(159,175,127)); 
  11.     m_InsideBoundryPenRight.CreatePen    (PS_INSIDEFRAME | PS_SOLID, 3, RGB(160,180,130)); 
  12.     m_InsideBoundryPenTop.CreatePen      (PS_INSIDEFRAME | PS_SOLID, 2, RGB(161,190,143)); 
  13.     m_InsideBoundryPenBottom.CreatePen   (PS_INSIDEFRAME | PS_SOLID, 2, RGB(140,155,  0)); 
  14.     m_InsideBoundryPenLeftSel.CreatePen  (PS_INSIDEFRAME | PS_SOLID, 3, RGB(153,198,252)); 
  15.     m_InsideBoundryPenRightSel.CreatePen (PS_INSIDEFRAME | PS_SOLID, 3, RGB(162,189,252)); 
  16.     m_InsideBoundryPenTopSel.CreatePen   (PS_INSIDEFRAME | PS_SOLID, 2, RGB(162,201,255)); 
  17.     m_InsideBoundryPenBottomSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(162,201,255)); 
  18.  
  19. CXPButton::~CXPButton() 
  20.     m_BoundryPen.DeleteObject(); 
  21.     m_InsideBoundryPenLeft.DeleteObject(); 
  22.     m_InsideBoundryPenRight.DeleteObject(); 
  23.     m_InsideBoundryPenTop.DeleteObject(); 
  24.     m_InsideBoundryPenBottom.DeleteObject(); 
  25.     m_InsideBoundryPenLeftSel.DeleteObject(); 
  26.     m_InsideBoundryPenRightSel.DeleteObject(); 
  27.     m_InsideBoundryPenTopSel.DeleteObject(); 
  28.     m_InsideBoundryPenBottomSel.DeleteObject(); 
  29.  
  30. BEGIN_MESSAGE_MAP(CXPButton, CButton) 
  31.     ON_WM_MOUSEMOVE() 
  32.     ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) 
  33.     ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover) 
  34.     ON_WM_ERASEBKGND() 
  35. END_MESSAGE_MAP() 
  36.  
  37. void CXPButton::PreSubclassWindow()  
  38.     CButton::PreSubclassWindow(); 
  39.     ModifyStyle(0, BS_OWNERDRAW); 
  40.  
  41. void CXPButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
  42.     CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); 
  43.     int nSaveDC = pDC->SaveDC(); 
  44.  
  45.     CPen* pcPenOld = pDC->SelectObject(&m_BoundryPen); 
  46.     CRect rect = lpDrawItemStruct->rcItem; 
  47.     POINT pt = {5, 5}; 
  48.     pDC->RoundRect(&rect, pt); 
  49.     pDC->SelectObject(pcPenOld); 
  50.  
  51.     UINT state = lpDrawItemStruct->itemState; 
  52.  
  53.     if (state & ODS_FOCUS) 
  54.     { 
  55.         m_bFocus = TRUE; 
  56.         m_bSelected = TRUE; 
  57.     } 
  58.     else 
  59.     { 
  60.         m_bFocus = FALSE; 
  61.         m_bSelected = FALSE; 
  62.     } 
  63.  
  64.     if (state & ODS_SELECTED || state & ODS_DEFAULT) 
  65.     { 
  66.         m_bFocus = TRUE; 
  67.     } 
  68.  
  69.     rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE))); 
  70.  
  71.     if (m_bOver || m_bSelected) 
  72.     { 
  73.         DrawInsideBorder(pDC, &rect); 
  74.     } 
  75.  
  76.     char strText[MAX_PATH + 1] = {0}; 
  77.     ::GetWindowText(m_hWnd, strText, MAX_PATH); 
  78.     if ( strlen(strText) > 0 ) 
  79.     { 
  80.         DrawText(pDC, rect, state, strText); 
  81.     } 
  82.  
  83.     pDC->RestoreDC(nSaveDC); 
  84.  
  85. void CXPButton::OnMouseMove(UINT nFlags, CPoint cPoint) 
  86.     if (!m_bTracking) 
  87.     { 
  88.         TRACKMOUSEEVENT cTrackMouseEvent; 
  89.         cTrackMouseEvent.cbSize = sizeof(cTrackMouseEvent); 
  90.         cTrackMouseEvent.dwFlags = TME_LEAVE | TME_HOVER; 
  91.         cTrackMouseEvent.hwndTrack = m_hWnd; 
  92.         cTrackMouseEvent.dwHoverTime = 1; 
  93.  
  94.         m_bTracking = _TrackMouseEvent(&cTrackMouseEvent); 
  95.     } 
  96.  
  97.     CButton::OnMouseMove(nFlags, cPoint); 
  98.  
  99. LRESULT CXPButton::OnMouseLeave(WPARAM wParam, LPARAM lParam) 
  100.     m_bOver = FALSE; 
  101.     m_bTracking = FALSE; 
  102.     InvalidateRect(NULL, FALSE); 
  103.     return 0; 
  104.  
  105. LRESULT CXPButton::OnMouseHover(WPARAM wParam, LPARAM lParam) 
  106.     m_bOver = TRUE; 
  107.     InvalidateRect(NULL); 
  108.     return 0; 
  109.  
  110. void CXPButton::DrawInsideBorder(CDC* pDC, CRect* rect) 
  111.     CPen* pLeft   = NULL; 
  112.     CPen* pRight  = NULL; 
  113.     CPen* pTop    = NULL; 
  114.     CPen* pBottom = NULL; 
  115.  
  116.     if (m_bSelected && !m_bOver) 
  117.     { 
  118.         pLeft   = &m_InsideBoundryPenLeftSel; 
  119.         pRight  = &m_InsideBoundryPenRightSel; 
  120.         pTop    = &m_InsideBoundryPenTopSel; 
  121.         pBottom = &m_InsideBoundryPenBottomSel; 
  122.     } 
  123.     else 
  124.     { 
  125.         pLeft   = &m_InsideBoundryPenLeft; 
  126.         pRight  = &m_InsideBoundryPenRight; 
  127.         pTop    = &m_InsideBoundryPenTop; 
  128.         pBottom = &m_InsideBoundryPenBottom; 
  129.     } 
  130.  
  131.     CPen* pcPenOld = pDC->SelectObject(pLeft); 
  132.     CPoint cPointOld = pDC->MoveTo(rect->left, rect->bottom - 1); 
  133.     pDC->LineTo(rect->left, rect->top + 1); 
  134.  
  135.     pDC->SelectObject(pRight); 
  136.     pDC->MoveTo(rect->right - 1, rect->bottom - 1); 
  137.     pDC->LineTo(rect->right - 1, rect->top); 
  138.  
  139.     pDC->SelectObject(pTop); 
  140.     pDC->MoveTo(rect->left - 1, rect->top); 
  141.     pDC->LineTo(rect->right - 1, rect->top); 
  142.  
  143.     pDC->SelectObject(pBottom); 
  144.     pDC->MoveTo(rect->left, rect->bottom); 
  145.     pDC->LineTo(rect->right - 1, rect->bottom); 
  146.  
  147.     pDC->SelectObject(pcPenOld); 
  148.     pDC->MoveTo(cPointOld); 
  149.     if (m_bSelected && !m_bOver) 
  150.     { 
  151.         DrawFocusRect(pDC->m_hDC, rect); 
  152.     } 
  153.  
  154. void CXPButton::DrawText(CDC* pDC, const CRect& rect, UINT state, LPCSTR strText) 
  155.     CFont* hFont = GetFont(); 
  156.     CFont* hOldFont = pDC->SelectObject(hFont); 
  157.     CSize szExtent = pDC->GetTextExtent(strText, lstrlen(strText)); 
  158.     CPoint pt(rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2); 
  159.  
  160.     if (state & ODS_SELECTED) 
  161.     { 
  162.         pt.Offset(1, 1); 
  163.     } 
  164.  
  165.     int nMode = pDC->SetBkMode(TRANSPARENT); 
  166.  
  167.     if (state & ODS_DISABLED) 
  168.     { 
  169.         pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL); 
  170.     } 
  171.     else 
  172.     { 
  173.         pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL); 
  174.     } 
  175.  
  176.     pDC->SelectObject(hOldFont); 
  177.     pDC->SetBkMode(nMode); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#ifndef _BTNST_H #define _BTNST_H // Uncomment the following line to enable support for sound effects #define BTNST_USE_SOUND #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 // Return values #ifndef BTNST_OK #define BTNST_OK 0 #endif #ifndef BTNST_INVALIDRESOURCE #define BTNST_INVALIDRESOURCE 1 #endif #ifndef BTNST_FAILEDMASK #define BTNST_FAILEDMASK 2 #endif #ifndef BTNST_INVALIDINDEX #define BTNST_INVALIDINDEX 3 #endif #ifndef BTNST_INVALIDALIGN #define BTNST_INVALIDALIGN 4 #endif #ifndef BTNST_BADPARAM #define BTNST_BADPARAM 5 #endif #ifndef BTNST_INVALIDPRESSEDSTYLE #define BTNST_INVALIDPRESSEDSTYLE 6 #endif // Dummy identifier for grayscale icon #ifndef BTNST_AUTO_GRAY #define BTNST_AUTO_GRAY (HICON)(0xffffffff - 1L) #endif class CXPButton : public CButton { public: CXPButton(); ~CXPButton(); enum { ST_ALIGN_HORIZ = 0, // Icon/bitmap on the left, text on the right ST_ALIGN_VERT, // Icon/bitmap on the top, text on the bottom ST_ALIGN_HORIZ_RIGHT, // Icon/bitmap on the right, text on the left ST_ALIGN_OVERLAP // Icon/bitmap on the same space as text }; enum { BTNST_COLOR_BK_IN = 0, // Background color when mouse is INside BTNST_COLOR_FG_IN, // Text color when mouse is INside BTNST_COLOR_BK_OUT, // Background color when mouse is OUTside BTNST_COLOR_FG_OUT, // Text color when mouse is OUTside BTNST_COLOR_BK_FOCUS, // Background color when the button is focused BTNST_COLOR_FG_FOCUS, // Text color when the button is focused BTNST_MAX_COLORS }; enum { BTNST_PRESSED_LEFTRIGHT = 0, // Pressed style from left to right (as usual) BTNST_PRESSED_TOPBOTTOM // Pressed style from top to bottom }; // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CXPButton) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); virtual BOOL PreTranslateMessage(MSG* pMsg); protected: virtual void PreSubclassWindow(); //}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值