www.pudn.com > SimplePlayer.rar > XPButton.cpp


// XPButton.cpp : implementation file 
// 
 
#include "stdafx.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 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CXPButton message handlers 
 
void CXPButton::PreSubclassWindow()  
{ 
	// TODO: Add your specialized code here and/or call the base class 
	 
	CButton::PreSubclassWindow(); 
	ModifyStyle(0, BS_OWNERDRAW); 
} 
 
void CXPButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
{ 
	// TODO: Add your code to draw the specified item 
	//从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; 
	 
	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 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::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; 
}