630 lines
14 KiB
C++
630 lines
14 KiB
C++
|
// ProgressBar.cpp : implementation file
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "ProgressBar.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
IMPLEMENT_DYNCREATE(CProgressBar, CProgressCtrl)
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CProgressBar, CProgressCtrl)
|
||
|
//{{AFX_MSG_MAP(CProgressBar)
|
||
|
ON_WM_ERASEBKGND()
|
||
|
//}}AFX_MSG_MAP
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::CProgressBar()
|
||
|
*
|
||
|
* Constructor for the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
CProgressBar::CProgressBar()
|
||
|
{
|
||
|
m_Rect.SetRect(0,0,0,0);
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::
|
||
|
*
|
||
|
* Constructor for the Progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* strMessage - Status message to display
|
||
|
* nSize - Max range of Progress control
|
||
|
* MaxValue - Max range of Progress control
|
||
|
* bSmooth - Smooth/Normal mode of progress display
|
||
|
* nPane - which pane to display the progress control
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
CProgressBar::CProgressBar(LPCTSTR strMessage, int nSize /*=100*/,
|
||
|
int MaxValue /*=100*/, BOOL bSmooth /*=FALSE*/,
|
||
|
int nPane/*=0*/)
|
||
|
{
|
||
|
Create(strMessage, nSize, MaxValue, bSmooth, nPane);
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::~CProgressBar()
|
||
|
*
|
||
|
* Destruction
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
CProgressBar::~CProgressBar()
|
||
|
{
|
||
|
Clear();
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::GetStatusBar()
|
||
|
*
|
||
|
* Returns the Status bar
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* CStatusBar* - Status bar to be returned
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
CStatusBar* CProgressBar::GetStatusBar()
|
||
|
{
|
||
|
CWnd *pMainWnd = AfxGetMainWnd();
|
||
|
if (!pMainWnd)
|
||
|
return NULL;
|
||
|
|
||
|
// If main window is a frame window, use normal methods...
|
||
|
if (pMainWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd)))
|
||
|
{
|
||
|
CWnd* pMessageBar = ((CFrameWnd*)pMainWnd)->GetMessageBar();
|
||
|
return DYNAMIC_DOWNCAST(CStatusBar, pMessageBar);
|
||
|
}
|
||
|
// otherwise traverse children to try and find the status bar...
|
||
|
else
|
||
|
return DYNAMIC_DOWNCAST(CStatusBar,
|
||
|
pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR));
|
||
|
}
|
||
|
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::Create()
|
||
|
*
|
||
|
* Creates a new progress control
|
||
|
* Create the CProgressCtrl as a child of the status bar positioned
|
||
|
* over the first pane, extending "nSize" percentage across pane.
|
||
|
* Sets the range to be 0 to MaxValue, with a step of 1.
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* strMessage - Status message to display
|
||
|
* nSize - Max range of Progress control
|
||
|
* MaxValue - Max range of Progress control
|
||
|
* bSmooth - Smooth/Normal mode of progress display
|
||
|
* nPane - which pane to display the progress control
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CProgressBar::Create(LPCTSTR strMessage, int nSize /*=100*/,
|
||
|
int MaxValue /*=100*/, BOOL bSmooth /*=FALSE*/, int nPane/*=0*/)
|
||
|
{
|
||
|
BOOL bSuccess = FALSE;
|
||
|
|
||
|
CStatusBar *pStatusBar = GetStatusBar();
|
||
|
if (!pStatusBar)
|
||
|
return FALSE;
|
||
|
|
||
|
DWORD dwStyle = WS_CHILD|WS_VISIBLE;
|
||
|
#ifdef PBS_SMOOTH
|
||
|
if (bSmooth)
|
||
|
dwStyle |= PBS_SMOOTH;
|
||
|
#endif
|
||
|
|
||
|
// Get CRect coordinates for requested status bar pane
|
||
|
CRect PaneRect;
|
||
|
pStatusBar->GetItemRect(nPane, &PaneRect);
|
||
|
|
||
|
// Create the progress bar
|
||
|
bSuccess = CProgressCtrl::Create(dwStyle, PaneRect, pStatusBar, 1);
|
||
|
ASSERT(bSuccess);
|
||
|
if (!bSuccess)
|
||
|
return FALSE;
|
||
|
|
||
|
// Set range and step
|
||
|
SetRange(0, MaxValue);
|
||
|
SetStep(1);
|
||
|
|
||
|
m_strMessage = strMessage;
|
||
|
m_nSize = nSize;
|
||
|
m_nPane = nPane;
|
||
|
m_strPrevText = pStatusBar->GetPaneText(m_nPane);
|
||
|
|
||
|
// Resize the control to its desired width
|
||
|
Resize();
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::Clear()
|
||
|
*
|
||
|
* Destroy the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
void CProgressBar::Clear()
|
||
|
{
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return;
|
||
|
|
||
|
// Hide the window. This is necessary so that a cleared
|
||
|
// window is not redrawn if "Resize" is called
|
||
|
ModifyStyle(WS_VISIBLE, 0);
|
||
|
|
||
|
CString str;
|
||
|
if (m_nPane == 0)
|
||
|
str.LoadString(AFX_IDS_IDLEMESSAGE); // Get the IDLE_MESSAGE
|
||
|
else
|
||
|
str = m_strPrevText; // Restore previous text
|
||
|
|
||
|
// Place the IDLE_MESSAGE in the status bar
|
||
|
CStatusBar *pStatusBar = GetStatusBar();
|
||
|
if (pStatusBar)
|
||
|
{
|
||
|
pStatusBar->SetPaneText(m_nPane, str);
|
||
|
pStatusBar->UpdateWindow();
|
||
|
}
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetText()
|
||
|
*
|
||
|
* Set the display text for the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CProgressBar::SetText(LPCTSTR strMessage)
|
||
|
{
|
||
|
m_strMessage = strMessage;
|
||
|
SetPaneText(m_nPane,m_strMessage);
|
||
|
return Resize();
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetSize()
|
||
|
*
|
||
|
* Set the size for the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* nSize - New size for the progress control
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CProgressBar::SetSize(int nSize)
|
||
|
{
|
||
|
m_nSize = nSize;
|
||
|
return Resize();
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetBarColour()
|
||
|
*
|
||
|
* Sets the color for the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* clrBar - Color for progress control
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* COLORREF last color of progress control
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
COLORREF CProgressBar::SetBarColour(COLORREF clrBar)
|
||
|
{
|
||
|
#ifdef PBM_SETBKCOLOR
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return CLR_DEFAULT;
|
||
|
|
||
|
return (COLORREF )SendMessage(PBM_SETBARCOLOR, 0, (LPARAM) clrBar);
|
||
|
#else
|
||
|
UNUSED(clrBar);
|
||
|
return CLR_DEFAULT;
|
||
|
#endif
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetBkColour()
|
||
|
*
|
||
|
* Sets the background color for the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* COLORREF last color of progress control background
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
COLORREF CProgressBar::SetBkColour(COLORREF clrBk)
|
||
|
{
|
||
|
#ifdef PBM_SETBKCOLOR
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return CLR_DEFAULT;
|
||
|
|
||
|
return (COLORREF) SendMessage(PBM_SETBKCOLOR, 0, (LPARAM) clrBk);
|
||
|
#else
|
||
|
UNUSED(clrBk);
|
||
|
return CLR_DEFAULT;
|
||
|
#endif
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetRange()
|
||
|
*
|
||
|
* Set the range limits for the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* nLower - Lower limit
|
||
|
* nUpper - Upper limit
|
||
|
* nStep - Step value
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* status
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CProgressBar::SetRange(int nLower, int nUpper, int nStep /* = 1 */)
|
||
|
{
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return FALSE;
|
||
|
|
||
|
// To take advantage of the Extended Range Values we use the PBM_SETRANGE32
|
||
|
// message intead of calling CProgressCtrl::SetRange directly. If this is
|
||
|
// being compiled under something less than VC 5.0, the necessary defines
|
||
|
// may not be available.
|
||
|
|
||
|
#ifdef PBM_SETRANGE32
|
||
|
ASSERT(-0x7FFFFFFF <= nLower && nLower <= 0x7FFFFFFF);
|
||
|
ASSERT(-0x7FFFFFFF <= nUpper && nUpper <= 0x7FFFFFFF);
|
||
|
SendMessage(PBM_SETRANGE32, (WPARAM) nLower, (LPARAM) nUpper);
|
||
|
#else
|
||
|
ASSERT(0 <= nLower && nLower <= 65535);
|
||
|
ASSERT(0 <= nUpper && nUpper <= 65535);
|
||
|
CProgressCtrl::SetRange(nLower, nUpper);
|
||
|
#endif
|
||
|
|
||
|
CProgressCtrl::SetStep(nStep);
|
||
|
return TRUE;
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetPos()
|
||
|
*
|
||
|
* Sets the current position for the progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* nPos - new Postion to be set
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* status
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
int CProgressBar::SetPos(int nPos)
|
||
|
{
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return 0;
|
||
|
|
||
|
#ifdef PBM_SETRANGE32
|
||
|
ASSERT(-0x7FFFFFFF <= nPos && nPos <= 0x7FFFFFFF);
|
||
|
#else
|
||
|
ASSERT(0 <= nPos && nPos <= 65535);
|
||
|
#endif
|
||
|
|
||
|
ModifyStyle(0,WS_VISIBLE);
|
||
|
return CProgressCtrl::SetPos(nPos);
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::OffestPos()
|
||
|
*
|
||
|
* Set the progress control's offset
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* nPos - Position offset
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* status
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
int CProgressBar::OffsetPos(int nPos)
|
||
|
{
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return 0;
|
||
|
|
||
|
ModifyStyle(0,WS_VISIBLE);
|
||
|
return CProgressCtrl::OffsetPos(nPos);
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetStep()
|
||
|
*
|
||
|
* Set progress control's step value
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* nStep - Step value to be set
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
int CProgressBar::SetStep(int nStep)
|
||
|
{
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return 0;
|
||
|
|
||
|
ModifyStyle(0,WS_VISIBLE);
|
||
|
return CProgressCtrl::SetStep(nStep);
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::StepIt()
|
||
|
*
|
||
|
* Step the progress control standard step value
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
int CProgressBar::StepIt()
|
||
|
{
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return 0;
|
||
|
|
||
|
ModifyStyle(0,WS_VISIBLE);
|
||
|
return CProgressCtrl::StepIt();
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::Resize()
|
||
|
*
|
||
|
* Resize the progress control to fit
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* status
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CProgressBar::Resize()
|
||
|
{
|
||
|
if (!IsWindow(GetSafeHwnd()))
|
||
|
return FALSE;
|
||
|
|
||
|
CStatusBar *pStatusBar = GetStatusBar();
|
||
|
if (!pStatusBar)
|
||
|
return FALSE;
|
||
|
|
||
|
// Redraw the window text
|
||
|
if (IsWindowVisible())
|
||
|
{
|
||
|
pStatusBar->SetPaneText(m_nPane, m_strMessage);
|
||
|
pStatusBar->UpdateWindow();
|
||
|
}
|
||
|
|
||
|
// Calculate how much space the text takes up
|
||
|
CClientDC dc(pStatusBar);
|
||
|
CFont *pOldFont = dc.SelectObject(pStatusBar->GetFont());
|
||
|
CSize size = dc.GetTextExtent(m_strMessage); // Length of text
|
||
|
int margin = dc.GetTextExtent(_T(" ")).cx * 2; // Text margin
|
||
|
dc.SelectObject(pOldFont);
|
||
|
|
||
|
// Now calculate the rectangle in which we will draw the progress bar
|
||
|
CRect rc;
|
||
|
pStatusBar->GetItemRect(m_nPane, rc);
|
||
|
|
||
|
// Position left of progress bar after text and right of progress bar
|
||
|
// to requested percentage of status bar pane
|
||
|
if (!m_strMessage.IsEmpty())
|
||
|
rc.left += (size.cx + 2*margin);
|
||
|
rc.right -= (rc.right - rc.left) * (100 - m_nSize) / 100;
|
||
|
|
||
|
if (rc.right < rc.left) rc.right = rc.left;
|
||
|
|
||
|
// Leave a litle vertical margin (10%) between the top and bottom of the bar
|
||
|
int Height = rc.bottom - rc.top;
|
||
|
rc.bottom -= Height/10;
|
||
|
rc.top += Height/10;
|
||
|
|
||
|
// If the window size has changed, resize the window
|
||
|
if (rc != m_Rect)
|
||
|
{
|
||
|
MoveWindow(&rc);
|
||
|
m_Rect = rc;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::OnEraseBkgnd()
|
||
|
*
|
||
|
* Resize, progress control
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* none
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* status
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CProgressBar::OnEraseBkgnd(CDC* pDC)
|
||
|
{
|
||
|
Resize();
|
||
|
return CProgressCtrl::OnEraseBkgnd(pDC);
|
||
|
}
|
||
|
/**************************************************************************\
|
||
|
* CProgressBar::SetPaneText()
|
||
|
*
|
||
|
* Set the text for the Pane (Status text for progress control)
|
||
|
*
|
||
|
*
|
||
|
* Arguments:
|
||
|
*
|
||
|
* nPane - pane number
|
||
|
* strText - Text to add to the status pane
|
||
|
*
|
||
|
* Return Value:
|
||
|
*
|
||
|
* status
|
||
|
*
|
||
|
* History:
|
||
|
*
|
||
|
* 2/14/1999 Original Version
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CProgressBar::SetPaneText(int nPane, LPCTSTR strText)
|
||
|
{
|
||
|
CStatusBar* pStatusBar = GetStatusBar();
|
||
|
if(pStatusBar != NULL)
|
||
|
{
|
||
|
pStatusBar->SetPaneText(nPane,strText);
|
||
|
pStatusBar->UpdateWindow();
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|