一个美观的进度条的使用

来源:互联网 发布:光子嫩肤 知乎 编辑:程序博客网 时间:2024/06/05 03:19

之前做一个项目的时候需要用到进度条,当时就觉得MFC提供的实在是太难看,

后来在网上扒拉了一个比较好看的。该进度条是继承了CStatic控件,所以在使用时,

需要添加一个CStatic控件,才能使用。该类的名称为CKCBusyProgressCtrl。具体

的函数使用,我就不解释了,这是我做的一个例子,如图:

        


该控件能改变前景色,边框颜色,运行速度,闪动个数,等等,如图

源代码已经放在http://download.csdn.net/detail/kaishang0713/6585277,如有需要,请下载




不能上传源代码,只能把CKCBusyProgressCtrl代码贴出来了,如下:

头文件:
#if !defined(AFX_BUSYPROGRESSCTRL_H__BEE47141_AAF5_44A5_8408_2C4452BD764A__INCLUDED_)
#define AFX_BUSYPROGRESSCTRL_H__BEE47141_AAF5_44A5_8408_2C4452BD764A__INCLUDED_


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// BusyProgressCtrl.h : header file
//


/////////////////////////////////////////////////////////////////////////////
// CKCBusyProgressCtrl window


//
// defines for the control's mode
#define BPC_MODE_BUSY0x00000001
#define BPC_MODE_PROGRESS0x00000002


//
// defines for the type of BUSY mode
#define BPC_BUSY_PINGPONG 0x00000001
#define BPC_BUSY_LTR0x00000002
#define BPC_BUSY_RTL0x00000004


//
// defines for the fill type of BUSY mode
#define BPC_BUSYFILL_BLOCK0x00000001
#define BPC_BUSYFILL_SMOOTH0x00000002


//
// custom message defines
#define BPM_SETNUMSTEPS (WM_USER+1)
#define BPM_SETCURPOS(WM_USER+2)
#define BPM_SETIBPAD(WM_USER+3)
#define BPM_SETSPEED(WM_USER+4)
#define BPM_SETRANGE(WM_USER+5)
#define BPM_SETMODE(WM_USER+6)
#define BPM_STARTBUSY (WM_USER+7)
#define BPM_ENDBUSY (WM_USER+8)
#define BPM_STEPIT(WM_USER+9)
// new in version 0.3
#define BPM_SETBUSYTYPE(WM_USER+10)
#define BPM_SETBUSYFILL(WM_USER+11)
#define BPM_SETGRANULARITY(WM_USER+12)
#define BPM_SETCOLBKG(WM_USER+13)
#define BPM_SETCOLBFACE(WM_USER+14)
#define BPM_SETCOLBEDGE(WM_USER+15)
#define BPM_SETCOLBFACEHI(WM_USER+16)
#define BPM_SETCOLBEDGEHI(WM_USER+17)
#define BPM_RECALC(WM_USER+18)
#define BPM_RESET(WM_USER+19)
#define BPM_USESYSCOL(WM_USER+20)


class CKCBusyProgressCtrl : public CStatic
{
// Construction
public:
CKCBusyProgressCtrl(int nNumSteps = 10, int nCurPos = 0);
virtual ~CKCBusyProgressCtrl();


//
// Methods

// since version 0.1
void Recalc();
void Reset();
void Start();
void End();
void StepIt();


void SetNumSteps(int nNumSteps){ m_nNumSteps = nNumSteps; Recalc(); }
int GetNumSteps(){ return m_nNumSteps; }
void SetCurPos(int nCurPos){ m_nCurPos = nCurPos; Invalidate(); }
int GetCurPos(){ return m_nCurPos; }
void SetInterBlockPadding(int nPadding){ m_nIBPadding = nPadding; Recalc(); }
int GetInterBlockPadding(){ return m_nIBPadding; }
void SetSpeed(int nSpeed){ m_nSpeed = nSpeed; }
int GetSpeed(){ return m_nSpeed; }
bool IsRunning(){ return (m_pThrd != NULL); }
void SetMode(int nMode = BPC_MODE_BUSY);
int GetMode(){ return m_nMode; }
void SetRange(int nLower, int nUpper){ m_nLower = nLower; m_nUpper = nUpper; }
void GetRange(int& nLower, int& nUpper){ nLower = m_nLower; nUpper = m_nUpper; }
// new in version 0.2
void UseSysColBkg(bool bUse = true);
void SetBusyType(int nType = BPC_BUSY_PINGPONG);
int GetBusyType(){ return m_nBusyType; }
void SetBusyFill(int nFill = BPC_BUSYFILL_BLOCK);
int GetBusyFill(){ return m_nBusyFill; }
void SetGranularity(int nGranularity = 5){ m_nGranularity = nGranularity; SetBusyFill(m_nBusyFill); }
int GetGranularity(){ return m_nGranularity; }

// since version 0.1
COLORREF GetColBkg() { return m_colBkg; }
void SetColBkg(COLORREF col){ m_colBkg = col; }
COLORREF GetColBlockFace() { return m_colBlockFace; }
void SetColBlockFace(COLORREF col){ m_colBlockFace = col; }
COLORREF GetColBlockEdge() { return m_colBlockEdge; }
void SetColBlockEdge(COLORREF col){ m_colBlockEdge = col; }
COLORREF GetColBlockFaceHi() { return m_colBlockFaceHi; }
void SetColBlockFaceHi(COLORREF col){ m_colBlockFaceHi = col; }
COLORREF GetColBlockEdgeHi() { return m_colBlockEdgeHi; }
void SetColBlockEdgeHi(COLORREF col){ m_colBlockEdgeHi = col; }


// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CKCBusyProgressCtrl)
public:
virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL


protected:


//
// Methods
virtual void DrawBackground(CDC& dc, CRect& rect);
void DrawBlocks(CDC& dc, CRect& rect);
virtual void DrawBlock(CDC& dc, CRect& rect);
virtual void DrawHiliteBlock(CDC& dc, CRect& rect);
virtual void DrawPartialBlock(CDC& dc, CRect& rect, int nPartial);


// thread
static UINT thrdBusy(LPVOID pParam);


//
// Attributes
int m_nNumSteps;
int m_nStep;
int m_nCurPos;
CRect m_rect;
int m_nIBPadding;
double m_dBlockHeight;
double m_dBlockWidth;
CWinThread* m_pThrd;
bool m_bBusyThrd;
int m_nSpeed;
int m_nMode;
int m_nLower;
int m_nUpper;
bool m_bUseSysColBkg;
int m_nBusyType;
int m_nBusyFill;
int m_nGranularity;
int m_nNumStepsSmooth;


// colours
COLORREF m_colBkg;
COLORREF m_colBlockFace;
COLORREF m_colBlockEdge;
COLORREF m_colBlockFaceHi;
COLORREF m_colBlockEdgeHi;


// drawing stuff
CDC m_memDC;
CBitmap m_memBmp;
CBitmap* m_pOldBmp;


// Generated message map functions
//{{AFX_MSG(CKCBusyProgressCtrl)
afx_msg void OnPaint();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnSysColorChange();
//}}AFX_MSG
afx_msg LRESULT OnSetNumSteps(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetCurPos(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetIBPad(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetSpeed(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetRange(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetMode(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnStartBusy(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnEndBusy(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnStepIt(WPARAM wParam, LPARAM lParam);
// new in version 0.3
afx_msg LRESULT OnSetBusyType(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetBusyFill(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetGranularity(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetColBkg(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetColBFace(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetColBEdge(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetColBFaceHi(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnSetColBEdgeHi(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnRecalc(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnReset(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnUseSysCol(WPARAM wParam, LPARAM lParam);


DECLARE_MESSAGE_MAP()
};


/////////////////////////////////////////////////////////////////////////////


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.


#endif // !defined(AFX_BUSYPROGRESSCTRL_H__BEE47141_AAF5_44A5_8408_2C4452BD764A__INCLUDED_)

源文件:

#include "stdafx.h"
#include "KCBusyProgressCtrl.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// CKCBusyProgressCtrl


CKCBusyProgressCtrl::CKCBusyProgressCtrl(int nNumSteps, int nCurPos)
: m_nNumSteps(nNumSteps)
, m_nStep(1)
, m_nCurPos(nCurPos)
, m_colBkg( GetSysColor( COLOR_BTNFACE ) )
, m_colBlockFace( RGB(160, 190, 220) )
, m_colBlockEdge( RGB(50, 90, 135) )
, m_colBlockFaceHi( RGB(190, 220, 255) )
, m_colBlockEdgeHi( RGB(50, 90, 135) )
, m_pOldBmp(NULL)
, m_nIBPadding(1)
, m_rect(0,0,0,0)
, m_dBlockHeight(0.0L)
, m_dBlockWidth(0.0L)
, m_bBusyThrd(false)
, m_pThrd(NULL)
, m_nSpeed(100)
, m_nMode(BPC_MODE_BUSY)
, m_nLower(0)
, m_nUpper(100)
, m_bUseSysColBkg(true)
, m_nBusyType(BPC_BUSY_LTR)
, m_nBusyFill(BPC_BUSYFILL_BLOCK)
, m_nGranularity(5)
, m_nNumStepsSmooth( m_nNumSteps * m_nGranularity )
{
}


/////////////////////////////////////////////////////////////////////////////


CKCBusyProgressCtrl::~CKCBusyProgressCtrl()
{
if ( m_pOldBmp )
{
m_memDC.SelectObject(m_pOldBmp);
m_memBmp.DeleteObject();
m_memDC.DeleteDC();
}
}


/////////////////////////////////////////////////////////////////////////////


BEGIN_MESSAGE_MAP(CKCBusyProgressCtrl, CStatic)
//{{AFX_MSG_MAP(CKCBusyProgressCtrl)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_SYSCOLORCHANGE()
//}}AFX_MSG_MAP
ON_MESSAGE(BPM_SETNUMSTEPS, OnSetNumSteps)
ON_MESSAGE(BPM_SETCURPOS, OnSetCurPos)
ON_MESSAGE(BPM_SETIBPAD, OnSetIBPad)
ON_MESSAGE(BPM_SETSPEED, OnSetSpeed)
ON_MESSAGE(BPM_SETRANGE, OnSetRange)
ON_MESSAGE(BPM_SETMODE, OnSetMode)
ON_MESSAGE(BPM_STARTBUSY, OnStartBusy)
ON_MESSAGE(BPM_ENDBUSY, OnEndBusy)
ON_MESSAGE(BPM_STEPIT, OnStepIt)
// new in version 0.3
ON_MESSAGE(BPM_SETBUSYTYPE, OnSetBusyType)
ON_MESSAGE(BPM_SETBUSYFILL, OnSetBusyFill)
ON_MESSAGE(BPM_SETGRANULARITY, OnSetGranularity)
ON_MESSAGE(BPM_SETCOLBKG, OnSetColBkg)
ON_MESSAGE(BPM_SETCOLBFACE, OnSetColBFace)
ON_MESSAGE(BPM_SETCOLBEDGE, OnSetColBEdge)
ON_MESSAGE(BPM_SETCOLBFACEHI, OnSetColBFaceHi)
ON_MESSAGE(BPM_SETCOLBEDGEHI, OnSetColBEdgeHi)
ON_MESSAGE(BPM_RECALC, OnRecalc)
ON_MESSAGE(BPM_RESET, OnReset)
ON_MESSAGE(BPM_USESYSCOL, OnUseSysCol)


END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CKCBusyProgressCtrl message handlers


void CKCBusyProgressCtrl::PreSubclassWindow() 
{
DWORD dwStyle = GetStyle();


// dwStyle |= SS_OWNERDRAW;
CStatic::PreSubclassWindow();
Recalc();
}


/////////////////////////////////////////////////////////////////////////////


BOOL CKCBusyProgressCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
BOOL bResult = CWnd::Create("STATIC", "BusyProgressCtrl", dwStyle, rect, pParentWnd, nID, pContext);

Recalc();


return bResult;
}


/////////////////////////////////////////////////////////////////////////////
// function : Recalc()
// description:Function used to recalculate the block sizes and
// optionally get the current client area
/////////////////////////////////////////////////////////////////////////////
void CKCBusyProgressCtrl::Recalc()
{
if ( m_rect.IsRectEmpty() )
GetClientRect(&m_rect);


CRect tRect = m_rect;


tRect.right -= (m_nNumSteps * m_nIBPadding);
m_dBlockWidth = ((double)tRect.Width() / (double)m_nNumSteps);
m_dBlockHeight = tRect.Height();
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::OnPaint() 
{
CPaintDC dc(this); // device context for painting


// create a memory dc if needs be
if ( !m_memDC.m_hDC )
{
m_memDC.CreateCompatibleDC(&dc);
m_memBmp.CreateCompatibleBitmap(&dc, m_rect.Width(), m_rect.Height());
m_pOldBmp = m_memDC.SelectObject(&m_memBmp);
}


DrawBackground(m_memDC, m_rect);
DrawBlocks(m_memDC, m_rect);


// render the final image
dc.BitBlt(0, 0, m_rect.Width(), m_rect.Height(), &m_memDC, 0, 0, SRCCOPY);
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::DrawBackground(CDC& dc, CRect& rect)
{
dc.FillSolidRect( &rect, m_colBkg );
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::DrawBlocks(CDC& dc, CRect& rect)
{
CRect bRect;
double dXOffset = 0;
int i;
CPen nPen, *pOldPen = NULL;
CBrush nBrush, *pOldBrush = NULL;


// create some drawing tools
nPen.CreatePen( PS_SOLID, 0, m_colBlockEdge );
nBrush.CreateSolidBrush( m_colBlockFace );
pOldPen = dc.SelectObject(&nPen);
pOldBrush = dc.SelectObject(&nBrush);


// create the initial rectangle
bRect.top = 0; bRect.bottom = (int) m_dBlockHeight;
bRect.left = 0; bRect.right = (int) m_dBlockWidth;
for ( i = 0; i < m_nNumSteps; i++ )
{
if ( m_nMode & BPC_MODE_BUSY )
{
switch ( m_nBusyFill )
{
case BPC_BUSYFILL_BLOCK:
{
if ( i == m_nCurPos )
DrawHiliteBlock(dc, bRect);
else
DrawBlock(dc, bRect);
}
break;


case BPC_BUSYFILL_SMOOTH:
{
double dDiff = (double)m_nNumStepsSmooth;
double dPerc = ((double) m_nCurPos / dDiff);
int nFull = (int) (dPerc*(double)m_nNumSteps)-1;
double dPerc2 = (((dPerc * (double)m_nNumSteps)-1) - nFull);
int nPartial = (int)(m_dBlockWidth * dPerc2);


if ( i <= nFull )
DrawHiliteBlock(dc, bRect);
else
{
DrawBlock(dc, bRect);
if ( i == nFull + 1 && nPartial )
DrawPartialBlock(dc, bRect, nPartial);
}
}
break;
}
}
else if ( m_nMode & BPC_MODE_PROGRESS )
{
double dDiff = (double)(m_nUpper - m_nLower);
double dPerc = ((double) m_nCurPos / dDiff);
int nFull = (int) (dPerc*(double)m_nNumSteps)-1;
double dPerc2 = (((dPerc * (double)m_nNumSteps)-1) - nFull);
int nPartial = (int)(m_dBlockWidth * dPerc2);


if ( i <= nFull )
DrawHiliteBlock(dc, bRect);
else
{
DrawBlock(dc, bRect);
if ( i == nFull + 1 && nPartial )
DrawPartialBlock(dc, bRect, nPartial);
}
}
// offset the rectangle a bit
dXOffset += m_dBlockWidth + (double) m_nIBPadding;
bRect.left = (int) dXOffset;
bRect.right = (int)(dXOffset + m_dBlockWidth);
}


// cleanup after ourselves...
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
nPen.DeleteObject();
nBrush.DeleteObject();
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::DrawBlock(CDC& dc, CRect& rect)
{
dc.Rectangle(&rect);
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::DrawHiliteBlock(CDC& dc, CRect& rect)
{
CPen nPen, *pOldPen = NULL;
CBrush nBrush, *pOldBrush = NULL;


// use the correct tools ;)
nPen.CreatePen( PS_SOLID, 0, m_colBlockEdgeHi );
nBrush.CreateSolidBrush( m_colBlockFaceHi );
pOldPen = dc.SelectObject(&nPen);
pOldBrush = dc.SelectObject(&nBrush);


// draw the block
dc.Rectangle(&rect);


// cleanup
dc.SelectObject(pOldPen);
dc.SelectObject(pOldBrush);
nPen.DeleteObject();
nBrush.DeleteObject();
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::DrawPartialBlock(CDC& dc, CRect& rect, int nPartial)
{
CRect pRect = rect;


pRect.DeflateRect(1, 1);
pRect.right = pRect.left + nPartial;
if ( pRect.right >= rect.right )
pRect.right = rect.right - 1;
dc.FillSolidRect(&pRect, m_colBlockFaceHi);
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::OnSize(UINT nType, int cx, int cy) 
{
CStatic::OnSize(nType, cx, cy);

GetClientRect(&m_rect);
if ( m_memDC.m_hDC )
{
// delete the dc to allow OnPaint to recreate the DC for the new size
m_memDC.SelectObject(m_pOldBmp);
m_memBmp.DeleteObject();
m_memDC.DeleteDC();
}
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::StepIt()
{
int nNumSteps = 0;


if ( m_nMode & BPC_MODE_BUSY)
{
switch ( m_nBusyFill )
{
case BPC_BUSYFILL_BLOCK:
nNumSteps = m_nNumSteps;
break;


case BPC_BUSYFILL_SMOOTH:
nNumSteps = m_nNumStepsSmooth;
break;
}


switch ( m_nBusyType )
{
case BPC_BUSY_PINGPONG:
{
// do a check for the left to right movement
if ( m_nCurPos >= nNumSteps-1 )
m_nStep = -1;
// check if we're done moving from right to left..
if ( m_nCurPos <= 0 )
m_nStep = 1;
}
break;


case BPC_BUSY_LTR:
{
if ( m_nCurPos == nNumSteps-1 )
m_nCurPos = -1;
}
break;


case BPC_BUSY_RTL:
{
if ( m_nCurPos == 0 )
m_nCurPos = nNumSteps;
}
break;
}
}
else if ( m_nMode & BPC_MODE_PROGRESS )
{
}


// update the position
m_nCurPos += m_nStep;


Invalidate();
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::SetMode(int nMode)
{
End(); 
if ( m_nMode >= BPC_MODE_BUSY && m_nMode <= BPC_MODE_PROGRESS )
{
m_nMode = nMode;
if ( m_nMode == BPC_MODE_PROGRESS )
m_nStep = 1;
}
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::Start()
{
if ( m_nMode & BPC_MODE_BUSY)
{
while ( m_pThrd || m_bBusyThrd)
End();
m_pThrd = AfxBeginThread(thrdBusy, this);
m_pThrd->m_bAutoDelete = false;
}
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::End()
{
if ( m_pThrd )
{
if ( m_bBusyThrd )
m_bBusyThrd = false;
WaitForSingleObject(m_pThrd->m_hThread, m_nSpeed*2);
delete m_pThrd;
m_pThrd = NULL;
}
else
m_bBusyThrd = false;
}


/////////////////////////////////////////////////////////////////////////////


UINT CKCBusyProgressCtrl::thrdBusy(LPVOID pParam)
{
CKCBusyProgressCtrl* pThis = (CKCBusyProgressCtrl*) pParam;


if ( !pThis )
return -1;


while ( pThis->m_bBusyThrd )
Sleep(pThis->m_nSpeed);
pThis->m_bBusyThrd = true;
while ( pThis->m_bBusyThrd )
{
pThis->StepIt();
Sleep(pThis->m_nSpeed);
}
pThis->m_bBusyThrd = false;


return 0;
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::Reset()
{
if ( m_nMode == BPC_MODE_BUSY )
{
m_nCurPos = m_nBusyType != BPC_BUSY_RTL ? 0 : 
m_nBusyFill != BPC_BUSYFILL_SMOOTH ? m_nNumSteps : 
m_nNumSteps * m_nGranularity;
m_nStep = m_nBusyType != BPC_BUSY_RTL ? 1 : -1;
}
else
{
m_nCurPos = 0;
m_nStep = 1;
}
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetNumSteps(WPARAM wParam, LPARAM lParam)
{
SetNumSteps((int)wParam);
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetCurPos(WPARAM wParam, LPARAM lParam)
{
SetCurPos( (int)wParam );
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetIBPad(WPARAM wParam, LPARAM lParam)
{
SetInterBlockPadding( (int) wParam );
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetSpeed(WPARAM wParam, LPARAM lParam)
{
SetSpeed( (int) wParam );
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetRange(WPARAM wParam, LPARAM lParam)
{
SetRange( (int) wParam, (int) lParam );
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetMode(WPARAM wParam, LPARAM lParam)
{
SetMode( (int) wParam );
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnStartBusy(WPARAM wParam, LPARAM lParam)
{
Start();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnEndBusy(WPARAM wParam, LPARAM lParam)
{
End();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnStepIt(WPARAM wParam, LPARAM lParam)
{
StepIt();
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetBusyType(WPARAM wParam, LPARAM lParam)
{
SetBusyType( (int) wParam );
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetBusyFill(WPARAM wParam, LPARAM lParam)
{
SetBusyFill( (int) wParam );
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetGranularity(WPARAM wParam, LPARAM lParam)
{
SetGranularity((int) wParam);
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetColBkg(WPARAM wParam, LPARAM lParam)
{
SetColBkg( (COLORREF) wParam );
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetColBFace(WPARAM wParam, LPARAM lParam)
{
SetColBlockFace( (COLORREF) wParam );
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetColBEdge(WPARAM wParam, LPARAM lParam)
{
SetColBlockEdge( (COLORREF) wParam );
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetColBFaceHi(WPARAM wParam, LPARAM lParam)
{
SetColBlockFaceHi( (COLORREF) wParam );
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnSetColBEdgeHi(WPARAM wParam, LPARAM lParam)
{
SetColBlockEdgeHi( (COLORREF) wParam );
Invalidate();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnRecalc(WPARAM wParam, LPARAM lParam)
{
Recalc();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnReset(WPARAM wParam, LPARAM lParam)
{
Reset();
return 0;
}


/////////////////////////////////////////////////////////////////////////////


LRESULT CKCBusyProgressCtrl::OnUseSysCol(WPARAM wParam, LPARAM lParam)
{
UseSysColBkg( wParam ? true : false );
return 0;
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::UseSysColBkg(bool bUse)
{
m_bUseSysColBkg = bUse;
if ( bUse )
m_colBkg = GetSysColor(COLOR_3DFACE);
Invalidate();
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::OnSysColorChange() 
{
CStatic::OnSysColorChange();

if ( m_bUseSysColBkg )
{
m_colBkg = GetSysColor(COLOR_3DFACE);
Invalidate();
}
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::SetBusyType(int nType)
{
m_nBusyType = nType;
if ( m_nMode == BPC_MODE_BUSY )
{
switch ( nType )
{
case BPC_BUSY_LTR:
m_nStep = 1;
break;


case BPC_BUSY_RTL:
m_nStep = -1;
break;


case BPC_BUSY_PINGPONG:
default:
break;
}
}
}


/////////////////////////////////////////////////////////////////////////////


void CKCBusyProgressCtrl::SetBusyFill(int nFill)
{
if ( m_nMode == BPC_MODE_BUSY )
{
m_nBusyFill = nFill;
switch ( nFill )
{
case BPC_BUSYFILL_SMOOTH:
Reset();
m_nNumStepsSmooth = m_nNumSteps * m_nGranularity;
break;


case BPC_BUSYFILL_BLOCK:
default:
Reset();
break;


}
}
}