www.pudn.com > VCдµÄMP3²¥·ÅÆ÷Ô´´úÂë.zip > HorverSlider.cpp


// HorverSlider.cpp : implementation file 
// 
 
#include "stdafx.h" 
 
#include "HorverSlider.h" 
#include  
 
 
#include "MemDC.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CHorverSlider 
 
CHorverSlider::CHorverSlider() 
{ 
	m_strText = "%ld°""; 
 
	m_bDragging = false; 
	m_nZero = 0; 
	m_crBack = RGB(0,0,0); 
	m_crX = RGB(255,0,0); 
} 
 
CHorverSlider::~CHorverSlider() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CHorverSlider, CSliderCtrl) 
	//{{AFX_MSG_MAP(CHorverSlider) 
	ON_WM_SIZE() 
	ON_WM_ERASEBKGND() 
	ON_WM_PAINT() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONUP() 
	ON_WM_KEYDOWN() 
	ON_WM_KEYUP() 
		// NOTE - the ClassWizard will add and remove mapping macros here. 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CHorverSlider message handlers 
void CHorverSlider::PreSubclassWindow()  
{ 
	CSliderCtrl::PreSubclassWindow(); 
 
	SetRange(0, 100, FALSE); 
	SetLineSize(1); 
	SetPageSize(10); 
 
	Init(); 
} 
 
BOOL CHorverSlider::PreCreateWindow(CREATESTRUCT& cs)  
{ 
	if(!CSliderCtrl::PreCreateWindow(cs)) return FALSE; 
 
	SetRange(0, 100, FALSE); 
	SetLineSize(1); 
	SetPageSize(10); 
 
	Init(); 
 
	return TRUE; 
} 
 
void CHorverSlider::OnSize(UINT nType, int cx, int cy)  
{ 
	CSliderCtrl::OnSize(nType, cx, cy); 
	 
	Init(); 
} 
 
void CHorverSlider::Init() 
{ 
	VerifyPos(); 
} 
 
BOOL CHorverSlider::OnEraseBkgnd(CDC* pDC)  
{ 
	return TRUE; 
} 
void CHorverSlider::OnPaint()  
{ 
	const int nMin = GetRangeMin(); 
	const int nMax = GetRangeMax()+1; 
 
	CPaintDC dc(this); // device context for painting 
 
	CMemDC pDC(&dc); 
	// Draw (clear) the background 
	CRect rc; 
	GetClientRect(rc); 
	pDC->SelectStockObject(NULL_BRUSH); 
	int nPos = ((GetPos()-nMin)*(rc.Width()-10)/(nMax-nMin)) + 5; 
	CRect rcTemp; 
	rcTemp = CRect(rc.left+5,rc.top+3,nPos,rc.bottom-3); 
	pDC->FillSolidRect(rc, m_crBack); 
	pDC->FillSolidRect(rcTemp,m_crX); 
	CRect rcTemp6 = CRect(rc.left+5,rc.top+3,rc.right-5,rc.bottom-3); 
	pDC->Draw3dRect(rcTemp6,RGB(0,255,255),RGB(0,255,255)); 
//	pDC->Rectangle(&rc); 
	// Draw the knob 
	int m_nKnobRadius = 5; 
	int nKnobRadius = m_nKnobRadius; 
	CPoint ptKnobCenter; 
	ptKnobCenter = CPoint(nPos,(rc.top +rc.bottom)/2); 
 
	const CRect rcKnob(ptKnobCenter.x - nKnobRadius, ptKnobCenter.y - nKnobRadius, ptKnobCenter.x + nKnobRadius, ptKnobCenter.y + nKnobRadius); 
 
	CRgn rgnKnob; 
	rgnKnob.CreateEllipticRgnIndirect(rcKnob); 
	CBrush brKnob(::GetSysColor(COLOR_BTNFACE)); 
	pDC->FillRgn(&rgnKnob, &brKnob); 
	rgnKnob.DeleteObject(); 
	if(m_bDragging) 
	{ 
		pDC->FillSolidRect(rcKnob,RGB(64,0,255)); 
		pDC->Draw3dRect(rcKnob,::GetSysColor(COLOR_3DHIGHLIGHT),::GetSysColor(COLOR_3DDKSHADOW)); 
		//DrawCircle(pDC, ptKnobCenter, --nKnobRadius, ::GetSysColor(COLOR_3DDKSHADOW), ::GetSysColor(COLOR_3DHIGHLIGHT)); 
//		DrawCircle(pDC, ptKnobCenter, --nKnobRadius, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DLIGHT)); 
	} 
	else 
	{ 
		pDC->FillSolidRect(rcKnob,RGB(0,0,160)); 
		pDC->Draw3dRect(rcKnob,::GetSysColor(COLOR_3DHIGHLIGHT),::GetSysColor(COLOR_3DDKSHADOW)); 
 
	//DrawCircle(pDC, ptKnobCenter, --nKnobRadius, ::GetSysColor(COLOR_3DHIGHLIGHT), ::GetSysColor(COLOR_3DDKSHADOW)); 
	//	DrawCircle(pDC, ptKnobCenter, --nKnobRadius, ::GetSysColor(COLOR_3DLIGHT), ::GetSysColor(COLOR_3DSHADOW)); 
	} 
 
	// Draw the focus circle on the inside of the knob 
	if(GetFocus() == this) 
	{ 
		DrawCircle(pDC, ptKnobCenter, nKnobRadius-2, RGB(0, 0, 0), TRUE); 
	} 
 
	// Don't call CSliderCtrl::OnPaint() 
} 
 
void CHorverSlider::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	if(!m_bDragging) 
	{ 
		m_bDragging = true; 
		m_bDragChanged = false; 
		SetCapture(); 
		SetFocus(); 
		if(SetKnob(point)) 
		{ 
			m_bDragChanged = true; 
			PostMessageToParent(TB_THUMBTRACK); 
		} 
		RedrawWindow(); 
	} 
	else 
	{ 
		CSliderCtrl::OnLButtonDown(nFlags, point); 
	} 
} 
 
void CHorverSlider::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	if(m_bDragging) 
	{ 
		if(SetKnob(point)) 
		{ 
			m_bDragChanged = true; 
			PostMessageToParent(TB_THUMBTRACK); 
			RedrawWindow(); 
		} 
	} 
	else 
	{ 
		CSliderCtrl::OnMouseMove(nFlags, point); 
	} 
} 
 
void CHorverSlider::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	if(m_bDragging) 
	{ 
		m_bDragging = false; 
		::ReleaseCapture(); 
		if(SetKnob(point)) 
		{ 
			PostMessageToParent(TB_THUMBTRACK); 
			m_bDragChanged = true; 
		} 
		if(m_bDragChanged) 
		{ 
			PostMessageToParent(TB_THUMBPOSITION); 
			m_bDragChanged = false; 
		} 
		RedrawWindow(); 
	} 
	else 
	{ 
		CSliderCtrl::OnLButtonUp(nFlags, point); 
	} 
} 
 
bool CHorverSlider::SetKnob(const CPoint& pt) 
{ 
	const int nMin = GetRangeMin(); 
	const int nMax = GetRangeMax()+1; 
	CRect rc; 
	GetClientRect(&rc); 
	POINT pt1; 
	pt1 = pt; 
	ScreenToClient(&pt1); 
	double dNewPos = 0.0; 
	dNewPos = pt.x - rc.left; 
   	const int nNewPos = nMin + (int)(dNewPos*(nMax-nMin)/(rc.Width()-10)); 
	const bool bChanged = (nNewPos != GetPos()); 
	if(bChanged) 
	{ 
		SetPos(nNewPos); 
	} 
 
	return bChanged; 
	 
} 
 
void CHorverSlider::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	const int nMin = GetRangeMin(); 
	const int nMax = GetRangeMax()+1; 
 
	switch(nChar) 
	{ 
	case VK_LEFT: 
	case VK_UP: 
		{ 
			int nNewPos = GetPos()-GetLineSize(); 
			while(nNewPos < nMin) nNewPos += (nMax - nMin); 
			SetPos(nNewPos); 
			RedrawWindow(); 
			PostMessageToParent(TB_LINEUP); 
		} 
		break; 
	 
	case VK_RIGHT: 
	case VK_DOWN: 
		{ 
			int nNewPos = GetPos()+GetLineSize(); 
			while(nNewPos >= nMax) nNewPos -= (nMax - nMin); 
			SetPos(nNewPos); 
			RedrawWindow(); 
			PostMessageToParent(TB_LINEDOWN); 
		} 
		break; 
 
	case VK_PRIOR: 
		{ 
			int nNewPos = GetPos()-GetPageSize(); 
			while(nNewPos < nMin) nNewPos += (nMax - nMin); 
			SetPos(nNewPos); 
			RedrawWindow(); 
			PostMessageToParent(TB_PAGEUP); 
		} 
		break; 
 
	case VK_NEXT: 
		{ 
			int nNewPos = GetPos()+GetPageSize(); 
			while(nNewPos >= nMax) nNewPos -= (nMax - nMin); 
			SetPos(nNewPos); 
			RedrawWindow(); 
			PostMessageToParent(TB_PAGEDOWN); 
		} 
		break; 
 
	case VK_HOME: 
	case VK_END: 
		// Do nothing (ignore keystroke) 
		break; 
 
	default: 
		CSliderCtrl::OnKeyDown(nChar, nRepCnt, nFlags); 
	} 
} 
 
void CHorverSlider::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	switch(nChar) 
	{ 
	case VK_LEFT: 
	case VK_UP: 
	case VK_RIGHT: 
	case VK_DOWN: 
	case VK_PRIOR: 
	case VK_NEXT: 
		PostMessageToParent(TB_ENDTRACK); 
		break; 
 
	case VK_HOME: 
	case VK_END: 
		// Do nothing 
		break; 
 
	default: 
		CSliderCtrl::OnKeyUp(nChar, nRepCnt, nFlags); 
	} 
} 
 
void CHorverSlider::PostMessageToParent(const int nTBCode) const 
{ 
	CWnd* pWnd = GetParent(); 
	if(pWnd) pWnd->PostMessage(WM_HSCROLL, (WPARAM)((GetPos() << 16) | nTBCode), (LPARAM)GetSafeHwnd()); 
} 
 
 
 
 
 
 
 
 
#ifdef _DEBUG 
void CHorverSlider::AssertValid() const 
{ 
	CSliderCtrl::AssertValid(); 
 
	ASSERT(m_nZero >= 0 && m_nZero < 360); 
//	ASSERT(m_nKnobRadius > 4); 
} 
 
void CHorverSlider::Dump(CDumpContext& dc) const 
{ 
	CSliderCtrl::Dump(dc); 
 
	dc	<< "m_strText = '" << m_strText << "'\n" 
//		<< "m_nKnobRadius = " << m_nKnobRadius << "\n" 
		<< "m_nZero = " << m_nZero; 
} 
#endif // _DEBUG