#include "stdafx.h"
#include "ProgressBar.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
ProgressBar::ProgressBar()
: m_error( false )
, m_total( 0 )
, m_progress( 0 )
, m_progressX( 0 )
{
}
ProgressBar::~ProgressBar()
{
}
BEGIN_MESSAGE_MAP(ProgressBar, CWnd)
//{{AFX_MSG_MAP(ProgressBar)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void
ProgressBar::OnPaint()
{
CPaintDC dc(this); // device context for painting
paint( dc );
}
// Paint the progress bar in response to a paint message
void
ProgressBar::paint( CDC &dc )
{
paintBackground( dc );
paintStatus( dc );
}
// Paint the background of the progress bar region
void
ProgressBar::paintBackground( CDC &dc )
{
CBrush brshBackground;
CPen penGray( PS_SOLID, 1, RGB (128, 128, 128) );
CPen penWhite( PS_SOLID, 1, RGB (255, 255, 255) );
VERIFY( brshBackground.CreateSolidBrush( ::GetSysColor (COLOR_BTNFACE) ) );
dc.FillRect( m_bounds, &brshBackground );
CPen *pOldPen = dc.SelectObject( &penGray );
int xRight = m_bounds.left + m_bounds.Width() -1;
int yBottom = m_bounds.top + m_bounds.Height() -1;
{
dc.MoveTo( m_bounds.left, m_bounds.top );
dc.LineTo( xRight, m_bounds.top );
dc.MoveTo( m_bounds.left, m_bounds.top );
dc.LineTo( m_bounds.left, yBottom );
}
dc.SelectObject( &penWhite );
{
dc.MoveTo( xRight, m_bounds.top );
dc.LineTo( xRight, yBottom );
dc.MoveTo( m_bounds.left, yBottom );
dc.LineTo( xRight, yBottom );
}
dc.SelectObject( pOldPen );
}
// Paint the actual status of the progress bar
void
ProgressBar::paintStatus( CDC &dc )
{
if ( m_progress <= 0 )
return;
CBrush brshStatus;
CRect rect( m_bounds.left, m_bounds.top,
m_bounds.left + m_progressX, m_bounds.bottom );
COLORREF statusColor = getStatusColor();
VERIFY( brshStatus.CreateSolidBrush( statusColor ) );
rect.DeflateRect( 1, 1 );
dc.FillRect( rect, &brshStatus );
}
// Paint the current step
void
ProgressBar::paintStep( int startX,
int endX )
{
CRect redrawBounds( m_bounds.left + startX-1, m_bounds.top,
m_bounds.left + endX, m_bounds.bottom );
RedrawWindow( redrawBounds );
}
// Setup the progress bar for execution over a total number of steps
void
ProgressBar::start( int total )
{
m_total = total;
reset ();
}
// Take one step, indicating whether it was a successful step
void
ProgressBar::step( bool successful )
{
m_progress++;
int x = m_progressX;
m_progressX = scale (m_progress);
if ( !m_error && !successful )
{
m_error = true;
x = 1;
}
paintStep( x, m_progressX );
}
// Map from steps to display units
int
ProgressBar::scale( int value )
{
if ( m_total > 0 )
return max( 1, value * (m_bounds.Width() - 1) / m_total );
return value;
}
// Reset the progress bar
void
ProgressBar::reset()
{
m_progressX = 1;
m_progress = 0;
m_error = false;
RedrawWindow( m_bounds );
UpdateWindow( );
}
void
ProgressBar::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
GetClientRect( &m_bounds );
m_progressX = scale (m_progress);
Invalidate();
}
BOOL
ProgressBar::OnEraseBkgnd( CDC *pDC )
{
return FALSE;
}
syntax highlighted by Code2HTML, v. 0.9.1