// XPButton.h
- /* 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);
- };
/* 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
- #include "stdafx.h"
- #include "XPButton.h"
- CXPButton::CXPButton()
- : m_bOver(FALSE)
- , m_bTracking(FALSE)
- , m_bSelected(FALSE)
- , m_bFocus(FALSE)
- {
- m_BoundryPen.CreatePen (PS_INSIDEFRAME | PS_SOLID, 1, RGB( 55, 98, 6));
- m_InsideBoundryPenLeft.CreatePen (PS_INSIDEFRAME | PS_SOLID, 3, RGB(159,175,127));
- m_InsideBoundryPenRight.CreatePen (PS_INSIDEFRAME | PS_SOLID, 3, RGB(160,180,130));
- m_InsideBoundryPenTop.CreatePen (PS_INSIDEFRAME | PS_SOLID, 2, RGB(161,190,143));
- m_InsideBoundryPenBottom.CreatePen (PS_INSIDEFRAME | PS_SOLID, 2, RGB(140,155, 0));
- m_InsideBoundryPenLeftSel.CreatePen (PS_INSIDEFRAME | PS_SOLID, 3, RGB(153,198,252));
- m_InsideBoundryPenRightSel.CreatePen (PS_INSIDEFRAME | PS_SOLID, 3, RGB(162,189,252));
- m_InsideBoundryPenTopSel.CreatePen (PS_INSIDEFRAME | PS_SOLID, 2, RGB(162,201,255));
- m_InsideBoundryPenBottomSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(162,201,255));
- }
- CXPButton::~CXPButton()
- {
- m_BoundryPen.DeleteObject();
- m_InsideBoundryPenLeft.DeleteObject();
- m_InsideBoundryPenRight.DeleteObject();
- m_InsideBoundryPenTop.DeleteObject();
- m_InsideBoundryPenBottom.DeleteObject();
- m_InsideBoundryPenLeftSel.DeleteObject();
- m_InsideBoundryPenRightSel.DeleteObject();
- m_InsideBoundryPenTopSel.DeleteObject();
- m_InsideBoundryPenBottomSel.DeleteObject();
- }
- BEGIN_MESSAGE_MAP(CXPButton, CButton)
- ON_WM_MOUSEMOVE()
- ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
- ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
- ON_WM_ERASEBKGND()
- END_MESSAGE_MAP()
- void CXPButton::PreSubclassWindow()
- {
- CButton::PreSubclassWindow();
- ModifyStyle(0, BS_OWNERDRAW);
- }
- void CXPButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- int nSaveDC = pDC->SaveDC();
- CPen* pcPenOld = pDC->SelectObject(&m_BoundryPen);
- CRect rect = lpDrawItemStruct->rcItem;
- POINT pt = {5, 5};
- pDC->RoundRect(&rect, pt);
- pDC->SelectObject(pcPenOld);
- UINT state = lpDrawItemStruct->itemState;
- 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;
- }
- rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));
- if (m_bOver || m_bSelected)
- {
- DrawInsideBorder(pDC, &rect);
- }
- char strText[MAX_PATH + 1] = {0};
- ::GetWindowText(m_hWnd, strText, MAX_PATH);
- if ( strlen(strText) > 0 )
- {
- DrawText(pDC, rect, state, strText);
- }
- pDC->RestoreDC(nSaveDC);
- }
- void CXPButton::OnMouseMove(UINT nFlags, CPoint cPoint)
- {
- if (!m_bTracking)
- {
- TRACKMOUSEEVENT cTrackMouseEvent;
- cTrackMouseEvent.cbSize = sizeof(cTrackMouseEvent);
- cTrackMouseEvent.dwFlags = TME_LEAVE | TME_HOVER;
- cTrackMouseEvent.hwndTrack = m_hWnd;
- cTrackMouseEvent.dwHoverTime = 1;
- m_bTracking = _TrackMouseEvent(&cTrackMouseEvent);
- }
- CButton::OnMouseMove(nFlags, cPoint);
- }
- LRESULT CXPButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
- {
- m_bOver = FALSE;
- m_bTracking = FALSE;
- InvalidateRect(NULL, FALSE);
- return 0;
- }
- LRESULT CXPButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
- {
- m_bOver = TRUE;
- InvalidateRect(NULL);
- return 0;
- }
- void CXPButton::DrawInsideBorder(CDC* pDC, CRect* rect)
- {
- CPen* pLeft = NULL;
- CPen* pRight = NULL;
- CPen* pTop = NULL;
- CPen* pBottom = NULL;
- 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;
- }
- CPen* pcPenOld = pDC->SelectObject(pLeft);
- CPoint cPointOld = pDC->MoveTo(rect->left, rect->bottom - 1);
- 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(pcPenOld);
- pDC->MoveTo(cPointOld);
- if (m_bSelected && !m_bOver)
- {
- DrawFocusRect(pDC->m_hDC, rect);
- }
- }
- void CXPButton::DrawText(CDC* pDC, const CRect& rect, UINT state, LPCSTR strText)
- {
- 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);
- }