Phill Heald
October 12th, 1999, 06:04 AM
I would like to place a progress indicator on the Application Status Bar, next to the CAP's indicator.
I would like to do this from within a document view.
How can I do this, or at least get hold of the Apps Status Bar.....
I would be very greatful for any suggestions.
Thanks
gbo
October 12th, 1999, 06:13 AM
Hi,
Take a look at the CLongOperation class available on www.Codeguru.com (Do a Search). It's simple and easy!
Looks like that is what you are looking for.
Another option is the XStatusBar Class. Somewhat more advanced.
Best Regards,
GBO.
Roger Allen
October 12th, 1999, 06:14 AM
To have a progress control in the status bar, you need to add some functions to the MainFrame of your app. The example code below does this for the first pane in the status bar (you will have to change the pane number in the code yo use a different one), allowing you to have a label before the progress telling you what the progress is related to. It ay be alittle complicatd for you needs (its a straight hack from one of my apps), but it will give you a good starting point.
To access the status bar, you will need to aquire a pointer to the mainframe, and then call the relevant functions to create the progress control, step it, and finaly destroy it when you have finished with it.
// Prepare progress bar
void CMainFrame::BeginProgress(CString fixedText, CString variableText)
{
// find the rectangle of the pane where we want the status bar
CSize size;
CString text = fixedText + variableText;
if (text.GetLength() == 0)
{
BeginProgress(0, fixedText, variableText);
}
else
{
// if we have text, the we need to move the position of the
// progress control to give room for the text to be displayed
CDC *pDC = NULL;
pDC = this->GetDC();
pDC->SaveDC();
pDC->SelectObject(m_wndStatusBar.GetFont());
size = pDC->GetTextExtent(text);
pDC->RestoreDC(-1);
ReleaseDC(pDC);
BeginProgress(size.cx, fixedText, variableText);
}
}
void CMainFrame::BeginProgress(int width, CString fixedText, CString variableText)
{
// find the rectangle of the pane where we want the status bar
CRect rc;
CString text = fixedText + variableText;
if (m_wndStatusBar.m_hWnd != NULL)
{
// this is where you will need to change the pane number
m_wndStatusBar.GetItemRect(0, &rc);
rc.left += width + 5;
m_wndStatusBar.SetPaneText(0, text);
VERIFY(m_ctlProgress.Create(WS_CHILD | WS_VISIBLE, rc, &m_wndStatusBar, 1));
m_ctlProgress.SetRange(0, 100);
m_ctlProgress.SetPos(0);
}
}
// Set progress bar
void CMainFrame::SetProgress(int nProg, CString fixedText, CString variableText)
{
CString text = fixedText + variableText;
ASSERT(nProg <= 100);
if (m_ctlProgress.m_hWnd != NULL)
{
m_ctlProgress.SetPos(nProg);
if (text != "")
{
// if we have text, the we need to check whether it will fit
// into the space provided for it - if it doesn't fit, we'll
// need to cut the string into the right size
CSize size;
CDC *pDC = NULL;
CRect rctPane,
rctProgress,
rctParent;
int textMaxWidth = 0;
m_wndStatusBar.GetItemRect(0, &rctPane);
m_ctlProgress.GetWindowRect(&rctProgress);
m_ctlProgress.GetParent()->GetWindowRect(&rctParent);
rctProgress -= CPoint(rctParent.left, rctParent.top);
textMaxWidth = rctProgress.left - rctPane.left - 5;
pDC = this->GetDC();
pDC->SaveDC();
pDC->SelectObject(m_wndStatusBar.GetFont());
size = pDC->GetTextExtent(text);
// is text too big?
if (size.cx > textMaxWidth)
{
// yes, it is - so cut it down from the middle
CString left = "",
right = "";
int middle = 0;
// split string into half
middle = variableText.GetLength()/2;
// left half, right half
left = variableText.Left(middle);
right = variableText.Right(variableText.GetLength()-middle);
// still too big (yes, will be the first time round)
while (size.cx > textMaxWidth)
{
// remove one character from the left half
left = left.Left(left.GetLength()-1);
text = fixedText + left + "..." + right;
// get new size
size = pDC->GetTextExtent(text);
// does it fit now?
if (size.cx <= textMaxWidth)
{
// yes, it fits, so we can break
break;
}
// remove one character from the right half
right = right.Right(right.GetLength()-1);
text = fixedText + left + "..." + right;
// get new size
size = pDC->GetTextExtent(text);
// does it fit now?
if (size.cx <= textMaxWidth)
{
// yes, it fits, so we can break
break;
}
}
}
pDC->RestoreDC(-1);
ReleaseDC(pDC);
m_wndStatusBar.SetPaneText(0, text);
}
}
}
// Clear up progress bar
void CMainFrame::EndProgress()
{
if (m_ctlProgress.m_hWnd != NULL)
{
m_ctlProgress.DestroyWindow();
m_wndStatusBar.SetPaneText(0, "");
}
}
Put these in your header file
public:
void BeginProgress(CString fixedText, CString variableText = "");
void BeginProgress(int width, CString fixedText, CString variableText = "");
void SetProgress(int nProg, CString fixedText = "", CString variableText = "");
void EndProgress();
HTH
Roger Allen
Q2 - [CB]RIGamortis
ICQ - 31764540
Thomas Ascher
October 12th, 1999, 06:18 AM
Hi, add a progress control to your mainframe and create it in OnCreate from CMainFrame. You can show it if you need it and hide it if not. to size the control override OnSize in CMainFrame.
class CMainFrame : public CMDIFrameWnd
{
public:
CProgressCtrl m_wndProgress;
};
// ID_INDICATOR_PROGRESS is a pane ID in the statusbar where you want your progress control
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
int nHorz;
CRect rc(0, 0, 0, 0);
UINT nID, nStyle;
m_wndStatusBar.GetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_PROGRESS),
nID, nStyle, nHorz) ;
m_wndStatusBar.SetPaneInfo(m_wndStatusBar.CommandToIndex(ID_INDICATOR_PROGRESS),
nID, nStyle | SBPS_NOBORDERS | SBPS_DISABLED, nHorz);
if(!m_wndProgress.Create(WS_CHILD | PBS_SMOOTH, rc, &m_wndStatusBar, -1))
{
TRACE("Failed to create progressbar inside statusbar\n");
return -1; // fail to create
}
return 0;
}
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIFrameWnd::OnSize(nType, cx, cy);
if(IsWindow(m_wndProgress.m_hWnd))
{
CRect rc;
m_wndStatusBar.GetItemRect(m_wndStatusBar.CommandToIndex(ID_INDICATOR_PROGRESS), &rc);
m_wndProgress.MoveWindow(rc, FALSE);
}
}
// to show the progress control from everywhere
((CMainFrame*)AfxGetMainWnd())->m_wndProgress.ShowWindow(TRUE);