www.pudn.com > StyleToolkit_demo_src.zip > StyleProgress.cpp


// 
// StyleProgress.cpp : Version 1.0 - see article at CodeProject.com 
// 
// Author:  Darren Sessions 
//           
// 
// Description: 
//     StyleProgress is a CProgressCtrl derived control that uses the Style class 
//	   and GDI+ to support different styles 
// 
// History 
//     Version 1.0 - 2008 June 20 
//     - Initial public release 
// 
// License: 
//     This software is released under the Code Project Open License (CPOL), 
//     which may be found here:  http://www.codeproject.com/info/eula.aspx 
//     You are free to use this software in any way you like, except that you  
//     may not sell this source code. 
// 
//     This software is provided "as is" with no expressed or implied warranty. 
//     I accept no liability for any damage or loss of business that this  
//     software may cause. 
// 
/////////////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "StyleProgress.h" 
 
StyleProgress::StyleProgress(void) 
{ 
	m_bCreated	= FALSE; 
	 
	// default gray 
	m_BackColor = RGB(0xC9, 0xC9, 0xC9); 
	// default green 
	m_ForeColor = RGB(0x00, 0xd3, 0x28); 
 
	m_Lower = 0;  
	m_Upper = 100;  
	m_Pos = 50; 
	m_Step = 5; 
 
	// default will step the bottom layer of the second stack 
	m_StepStackIdx = -1; 
	m_StepLayerIdx = 0; 
	m_StepLayerWidth = 0; 
} 
 
StyleProgress::~StyleProgress(void) 
{ 
} 
 
BEGIN_MESSAGE_MAP(StyleProgress, CProgressCtrl) 
	ON_WM_ERASEBKGND() 
	ON_WM_PAINT() 
	ON_WM_NCPAINT() 
END_MESSAGE_MAP() 
 
void StyleProgress::OnPaint() 
{ 
	CPaintDC dc(this); // device context for painting 
 
	// need to create if default 
	if(!m_bCreated) CreateDefaultStack(); 
 
	m_Style.PaintStyle(&dc, m_ProgRect); 
} 
 
BOOL StyleProgress::OnEraseBkgnd(CDC* pDC) 
{ 
	return TRUE; 
} 
 
void StyleProgress::OnNcPaint() 
{ 
	// Needed to stop the base from painting the border 
} 
 
void StyleProgress::AddStack(Stack stack) 
{ 
	m_Style.AddStack(stack); 
} 
 
void StyleProgress::AddStepStack(Stack stack) 
{ 
	// this function must get called, so get m_ProgRect here 
	GetClientRect(m_ProgRect); 
	m_StepStackIdx = m_Style.AddStack(stack); 
 
	// default layer is zero - over ridden in SetStepLayer 
	m_StepLayerWidth = m_Style.m_Stacks[m_StepStackIdx].m_Layers[0].lrect.Width; 
 
	// the step layer needs to have its rect defined 
	// e.g. use the rect version FillSolid(rect, Blue) instead of FillSolid(Blue) 
	ASSERT(m_StepLayerWidth != 0); 
 
	m_bCreated = TRUE; 
} 
 
void StyleProgress:: SetStepLayer(int layerIdx) 
{ 
	// AddStepStack needs to be called before this funtion is called 
	ASSERT(m_StepStackIdx != -1); 
 
	m_StepLayerIdx = layerIdx;  
	m_StepLayerWidth = m_Style.m_Stacks[m_StepStackIdx].m_Layers[layerIdx].lrect.Width; 
} 
 
void StyleProgress::SetForeColor(COLORREF color, int Alpha) 
{ 
	m_ForeColor = color; 
	m_ForeAlpha = Alpha; 
} 
 
void StyleProgress::SetBackColor(COLORREF color, int Alpha) 
{ 
	m_BackColor = color; 
	m_BackAlpha = Alpha; 
} 
 
void StyleProgress::UpdateStack() 
{ 
	Rect frc, lrc; CRect crc; 
	float ratio; int width; 
 
	// AddStepStack needs to be called for 1 stack 
	ASSERT(m_StepStackIdx != -1); 
 
	// get the frame rect 
	frc = m_Style.m_Stacks[m_StepStackIdx].Frame.frect; 
	 
	// calculate step position 
	ratio = float(m_Pos)/float(m_Upper - m_Lower); 
	width = (int)(ratio*m_StepLayerWidth); 
 
	// adjust the rects 
	frc.Width = width; 
	lrc.Width = width; 
 
	// set the new rects 
	m_Style.m_Stacks[m_StepStackIdx].Frame.frect = frc; 
	m_Style.m_Stacks[m_StepStackIdx].Regenerate(m_StepLayerIdx); 
 
	// need to regenerate any stacks above this one 
	for(int i = (m_StepStackIdx+1); i < (int)m_Style.m_Stacks.size(); i++) 
	{ 
		m_Style.m_Stacks[i].Regenerate(); 
	} 
} 
 
int StyleProgress::SetStep(int step) 
{ 
	if(step <= m_Upper) 
	{ 
		m_Step = step; 
	} 
	return m_Step; 
} 
 
void StyleProgress::SetRange(int lower, int upper) 
{ 
	// negative range values not implemented 
	ASSERT(lower >= 0 && upper > 0); 
 
	if(upper > lower) 
	{ 
		m_Upper = upper;  
		m_Lower = lower; 
	} 
} 
int StyleProgress::SetPos(int pos) 
{ 
	if		(pos <= m_Lower)	m_Pos = m_Lower; 
	else if	(pos >= m_Upper)	m_Pos = m_Upper; 
	else						m_Pos = pos; 
 
	if(!m_bCreated) CreateDefaultStack(); 
 
	UpdateStack(); 
	Invalidate(); 
	 
	return m_Pos; 
} 
 
int StyleProgress::StepIt() 
{ 
	int newPos = m_Pos + m_Step; 
 
	if		(m_Pos == m_Upper)	m_Pos = m_Step; 
	else if	(newPos > m_Upper)	m_Pos = m_Upper; 
	else						m_Pos = newPos; 
 
	if(m_bCreated) 
	{ 
		UpdateStack(); 
		Invalidate(); 
	} 
 
	return m_Pos; 
} 
 
//////////////////////////////////////// 
/// DEFAULT PROGRESS CONTOL STACK ////// 
//////////////////////////////////////// 
void StyleProgress::CreateDefaultStack() 
{ 
	// define the rects 
	GetClientRect(m_ProgRect); CRect EffRect(m_ProgRect); CRect TopRect(m_ProgRect);  
 
	// some adustments 
	EffRect.DeflateRect(1, 1);  
	TopRect.DeflateRect(1, 1);  
 
	//=============== Background Layers ===================// 
	Stack ProgressBack(m_ProgRect, m_BackColor); 
 
	ProgressBack.SetShape(ROUNDRECT, 1); 
	ProgressBack.SetOuterBorder(1, RGB(0xB2, 0xB2, 0xB2)); 
	ProgressBack.SetMiddleBorder(1, Clr(100,White)); 
	 
	ProgressBack.FillBar(EffRect, LEFT_EDGE, 8, Clr(40,Black), Clr(0,Black)); 
	ProgressBack.FillBar(EffRect, RIGHT_EDGE, 8, Clr(0,Black), Clr(40,Black)); 
 
	float btprof[3] = { 0.0f, 0.20f, 1.0f }; 
	ProgressBack.FillBar(EffRect, TOP_EDGE, 6, Clr(200,White), Clr(241,White), Clr(40,White), btprof); 
	float bbprof[3] = { 0.0f, 0.80f, 1.0f }; 
	ProgressBack.FillBar(EffRect, BOTTOM_EDGE, 6, Clr(0,White), Clr(100,White), Clr(80,White), bbprof); 
 
	//=========== Foreground Layers ======================// 
 
	Stack ProgressFront(TopRect); 
	ProgressFront.FillSolid(TopRect, m_ForeColor); 
 
	// top and bottom 
 
	float tprof[3] = { 0.0f, 0.15f, 1.0f }; 
 
	ProgressFront.FillBar(TopRect, TOP_EDGE, 6, Clr(180,White), Clr(200,White), Clr(128,White), tprof); 
	ProgressFront.FillBar(TopRect, BOTTOM_EDGE, 6, Clr(0,White), Clr(100,White)); 
 
	float lprof[3] = { 0.0f, 0.15f, 1.0f }; 
	float rprof[3] = { 0.0f, 0.85f, 1.0f }; 
 
	ProgressFront.FillBar(TopRect, LEFT_EDGE, 20, Clr(20,Black), Clr(40,Black), Clr(0,Black), lprof); 
	ProgressFront.FillBar(TopRect, RIGHT_EDGE, 20, Clr(0,Black), Clr(40,Black), Clr(20,Black), rprof); 
 
	// add it to the style 
	AddStack(ProgressBack); 
	AddStepStack(ProgressFront); 
}