#include "stdafx.h" #include "CustomBtnStyle.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CustomBtnStyle::CustomBtnStyle(void) { m_BoundryPen.CreatePen(PS_INSIDEFRAME | PS_SOLID, 1, RGB(0, 0, 0));//按钮的外边框画笔 m_InsideBoundryPenLeft.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(176, 226, 255)); m_InsideBoundryPenRight.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(176, 226, 255)); m_InsideBoundryPenTop.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(176, 226, 255)); m_InsideBoundryPenBottom.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(176, 226, 255)); //按钮的背景色 m_FillActive.CreateSolidBrush(RGB(176, 226, 255)); 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; } CustomBtnStyle::~CustomBtnStyle(void) { 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(CustomBtnStyle, CButton) ON_WM_MOUSEMOVE() ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover) END_MESSAGE_MAP() //添加Owner Draw属性 void CustomBtnStyle::PreSubclassWindow() { CButton::PreSubclassWindow(); ModifyStyle(0, BS_OWNERDRAW); } void CustomBtnStyle::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 CustomBtnStyle::OnMouseLeave(WPARAM wParam, LPARAM lParam) { m_bOver = FALSE; m_bTracking = FALSE; InvalidateRect(NULL, FALSE); return 0; } LRESULT CustomBtnStyle::OnMouseHover(WPARAM wParam, LPARAM lParam) { m_bOver = TRUE; InvalidateRect(NULL); return 0; } void CustomBtnStyle::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { //从lpDrawItemStruct获取控件的相关信息 CRect rect = lpDrawItemStruct->rcItem; CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC); int nSaveDC=pDC->SaveDC(); UINT state = lpDrawItemStruct->itemState; POINT pt ; CString strText; GetWindowText(strText); //画按钮的外边框,它是一个半径为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); //显示按钮的文本 COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(0,191,255)); ::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(), &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER); ::SetTextColor(lpDrawItemStruct->hDC, crOldColor); } //绘制按钮的底色 void CustomBtnStyle::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 (int i = rect->top; i <= nHeight + 2; i ++) { rct.SetRect(rect->left, i, nWidth + 2, i + 1); pDC->FillRect(&rct, &brBk[((i * 63) / nHeight)]); } for (int i = 0; i < 64; i ++) brBk[i].DeleteObject(); } //绘制按钮的内边框 void CustomBtnStyle::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); }