123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- // XPButton.cpp : implementation file
- //
- #include "stdafx.h"
- #include "XPButton.h"
- #include ".\xpbutton.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CXPButton
- CXPButton::CXPButton()
- {
- 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;
- }
- CXPButton::~CXPButton()
- {
- 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(CXPButton, CButton)
- //{{AFX_MSG_MAP(CXPButton)
- ON_WM_MOUSEMOVE()
- ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
- ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
- //}}AFX_MSG_MAP
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CXPButton message handlers
- //添加Owner Draw属性
- void CXPButton::PreSubclassWindow()
- {
- // TODO: Add your specialized code here and/or call the base class
-
- CButton::PreSubclassWindow();
- ModifyStyle(0, BS_OWNERDRAW);
- }
- void CXPButton::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 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::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 CXPButton::DoGradientFill(CDC *pDC, CRect* rect)
- {
- CBrush brBk[64];
- int nWidth = rect->Width();
- int nHeight = rect->Height();
- CRect rct;
-
- int i = 0;
- for ( 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 CXPButton::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);
- }
- void CXPButton::OnLButtonDown(UINT nFlags, CPoint point)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- CButton::OnLButtonDown(nFlags, point);
- }
- void CXPButton::OnLButtonUp(UINT nFlags, CPoint point)
- {
- // TODO: 在此添加消息处理程序代码和/或调用默认值
- CButton::OnLButtonUp(nFlags, point);
- }
|