Progress control with Text

 Download Source Code and Example Project.



Latest Changes (Jeremy Davis) 26th May 1998

This is a simple CProgressCtrl derived class that allows text to be displayed on top of the progress bar in much the same way as many "Setup" programs display the progress of long operations.

The control is extremely simple and allows the same operations as a standard CProgressCtrl, as well as:

	void SetShowText(BOOL bShow);

which determines whether or not the text for the control will be displayed during updates. To set the text to be displayed use the standard CWnd::SetWindowText. If you call SetShowText(TRUE) but do not specify any window text using CWnd::SetWindowText, then the percentage fraction of progress will be displayed as default.

To use the control, just include a CProgressCtrl in your app as per usual (either dynamically or by using a dialog template) and change the variable type from CProgressCtrl to CTextProgressCtrl. (Make sure you include TextProgressCtrl.h)

At present the progress is only displayed as a smooth bar. (This may be changed in the future versions.)

Acknowledgements
Thanks to Keith Rule for his CMemDC class.

Modifications
26 May 1998 : Jeremy Davis added SetForeColour, SetBkColour, SetTextForeColour, SetTextBkColour, GetForeColour, GetBkColour, GetTextForeColour, GetTextBkColour.

void SetForeColour(COLORREF col) Sets the bar colour of the progress bar.
void SetBkColour(COLORREF col) Sets the background colour of the progress bar.
void SetTextForeColour(COLORREF col) Sets the colour of the text when the bar is not covering it.
void SetTextBkColour(COLORREF col) Set the colour of the text when the bar is covering it.
COLORREF GetForeColour() Returns the bar colour of the progress bar.
COLORREF GetBkColour() Returns the background colour of the progress bar.
COLORREF GetTextForeColour() Returns the colour the the text when the bar is not covering it.
COLORREF GetTextBkColour() Returns the colour of the text when the bar is covering it.

Last updated: 30 May 1998



Comments

  • Hvor lang tid det tager at rejse Dr. Dre Beats

    Posted by wanzixiao on 06/04/2013 12:21pm

    [url=http://www.beatsbydrdredanmark.webgarden.com/]beats by dre danmark[/url] If you don’t abuse your headphones, this shouldn’t be a problem. However, it’s worth noting since the headphone line after which these are styled—the Beats by Dr. Dre—doesn’t suffer from this issue. Simply put, the comparisons of the Beats line with the Zoro are only skin deep—they don’t sound similar and they aren’t built for the same type of usage.Despite the minor distortion at top volumes and the delicate nature of the drivers, the Noontec Zoro is a pretty solid audio performer at normal listening levels. The detachable cable adds a bit of value to the purchase, even if doesn’t feature an inline remote. [url=http://www.nyebeatsbydrdre.350.com/]beats by dre danmark[/url] Projektet kan opnås på en måde at bruge god til handling og magt lav overflod, og værdiskabende tilbehør. Den faktiske headset komfort element er virkelig stor. Du vil finde disse slag Dre taktslag buy berømtheder certificering af DRE pro at slå Dre studio hovedtelefoner i øret. BIII komme med en rengøringsklud til at sikre, at de er på udkig efter. For nylig fandt jeg en fælles ven kørte vej sat på afDr. Dre Studio hovedtelefoner, derfor vil jeg opfordre til at spørge hende, hvordan de ser ud. [url=http://www.beatsbydrdredanmark.weebly.com/]Beats by dre danmark[/url] Butland afsløret i en besked til en anden GB fodboldspiller, Karen Carney, at en Beats repræsentant besøgte holdet hotel på mandag, twitte: “. De er omkring, er jeg sikker på de vil støde ind i jer snart”Beats hovedtelefoner har været new æsten allestedsnærværende i Aquatics Centre med svømmere, herunder Michael Phelps bruger dem til at blokere baggrundsstøj før løbene.Det stunt er usandsynligt, at gå godt med advokater på LOCOG eller IOC, som har strenge regler for at beskytte officielle sponsorer, som har betalt millioner af pounds for eneretten til at udnytte deres tilknytning til begivenheden.Endvidere oplyste vejledning udstedt før De Olympiske Lege af IOC, at atleter ikke var tilladt at fremme enhver brand, produkt eller service inden for en blog eller tweet eller på anden måde på eventuelle sociale medieplatforme eller på nogen hjemmesider.

    Reply
  • interesting

    Posted by Diana104 on 03/28/2011 10:05am

    Your article is very interesting thanks a lot but i'mn trying to implement your code in VS 2008 but i'm having the following error if you can help: error C2440: 'static_cast'B_: impossible de convertir de 'LRESULT (__thiscall CTextProgressCtrl::* )(UINT,LPCTSTR)' en 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)' thx in advance

    Reply
  • Error compiling in VC7

    Posted by Legacy on 09/27/2002 12:00am

    Originally posted by: FrAnK

    When compiling the code in VC7 the following error occures:

    D:\Projects\MinorApp\TextProgressCtrl.cpp(152) : error C2440: 'static_cast' : cannot convert from 'LRESULT (__cdecl *)(UINT,LPTSTR)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'

    Even when changing to WPARAM and LPARAM the code will not compile!

    It worked great with VC6!

    Is there a setting in VC7 I should switch on (or off!) ?

    FrAnK.

    • For VC7

      Posted by Gyuha on 05/14/2004 10:19pm

      TextProgressCtrl.h
      ================
      afx_msg LRESULT OnSetText(WPARAM , LPARAM szText);
      afx_msg LRESULT OnGetText(WPARAM cchTextMax, LPARAM szText);
      
      TextProgressCtrl.cpp
      ========================
      LRESULT CTextProgressCtrl::OnSetText(WPARAM, LPARAM szText)
      {
          LRESULT result = Default();
      
          if ( (!szText && m_strText.GetLength()) ||
               (szText && (m_strText != (LPCTSTR)szText))   )
          {
              m_strText = (LPCTSTR)szText;
              Invalidate();
          }
      
          return result;
      }
      
      LRESULT CTextProgressCtrl::OnGetText(WPARAM cchTextMax, LPARAM szText)
      {
      	if (!_tcsncpy((LPTSTR)szText, m_strText, (UINT)cchTextMax))
              return 0;
          else 
      		return min(cchTextMax, (UINT)m_strText.GetLength());
      }
      
      .............
      Good Luck...

      Reply
    Reply
  • Small change to class so you don't have to keep track of an i variable and set position

    Posted by Legacy on 12/25/2001 12:00am

    Originally posted by: Eric Steimle

    Not to mess with other peoples stuff but...  I didn't feel like setting an int variable along with calling SetPos and I wanted a little change to the control so I could just add any text before the 25% or x% that the control all ready generates (maybe I'm just lazy).  I made the following single line change to the CtextProgressCtrl class in CtextProgressCtrl.cpp file on line 219 in the OnPaint fuction.
    
    

    if (m_bShowText)
    {
    CString str;
    if (m_strText.GetLength())
    //str = m_strText;
    str.Format(" %s%d%%",m_strText,(int)(Fraction*100.0));//Eric changed this line
    else
    str.Format(" %d%%", (int)(Fraction*100.0));

    dc.SetBkMode(TRANSPARENT)

    Now I can call something like this
    m_ProgressBar.SetShowText(true);
    m_ProgressBar.SetPos(25);
    m_ProgressBar.SetRange(0,100);
    CString str;
    str.Format("Processing completed");
    m_ProgressBar.SetWindowText(str);

    and the control will show Processing completed 25% in the progress bar. Call me lazy but I didn't feel like setting the i every time.

    Reply
  • http://www.codeguru.com/controls/text_progressctrl.shtml

    Posted by Legacy on 12/25/2001 12:00am

    Originally posted by: Eric Steimle

    Not to mess with other peoples stuff but...  I didn't feel like setting an int variable along with calling SetPos and I wanted a little change to the control so I could just add any text before the 25% or x% that the control all ready generates (maybe I'm just lazy).  I made the following single line change to the CtextProgressCtrl class in CtextProgressCtrl.cpp file on line 219 in the OnPaint fuction.
    
    

    if (m_bShowText)
    {
    CString str;
    if (m_strText.GetLength())
    //str = m_strText;
    str.Format(" %s%d%%",m_strText,(int)(Fraction*100.0));//Eric changed this line
    else
    str.Format(" %d%%", (int)(Fraction*100.0));

    dc.SetBkMode(TRANSPARENT)

    Now I can call something like this
    m_ProgressBar.SetShowText(true);
    m_ProgressBar.SetPos(25);
    m_ProgressBar.SetRange(0,100);
    CString str;
    str.Format("Processing completed");
    m_ProgressBar.SetWindowText(str);

    and the control will show Processing completed 25% in the progress bar. Call me lazy but I didn't feel like setting the i every time.

    Reply
  • Here are changes for ProgressCtrl messages PBM_

    Posted by Legacy on 10/26/2001 12:00am

    Originally posted by: Krazer

    Hope this works, wrote it for most of them but I only used StepIT and SetPOS.
    
    

    BEGIN_MESSAGE_MAP(CTextProgressCtrl, CProgressCtrl)
    //{{AFX_MSG_MAP(CTextProgressCtrl)
    ON_WM_ERASEBKGND()
    ON_WM_PAINT()
    ON_WM_SIZE()
    //}}AFX_MSG_MAP
    ON_MESSAGE(WM_SETTEXT, OnSetText)
    ON_MESSAGE(WM_GETTEXT, OnGetText)
    ON_MESSAGE(PBM_SETSTEP, OnSetStep)
    ON_MESSAGE(PBM_STEPIT, OnStepIt)
    ON_MESSAGE(PBM_GETPOS, OnGetPos)
    ON_MESSAGE(PBM_SETPOS, OnSetPos)
    ON_MESSAGE(PBM_DELTAPOS, OnDeltaPos)
    ON_MESSAGE(PBM_SETBARCOLOR, OnSetBarColor)
    ON_MESSAGE(PBM_SETBKCOLOR, OnSetBkColor)
    ON_MESSAGE(PBM_GETRANGE, OnGetRange)
    ON_MESSAGE(PBM_SETRANGE, OnSetRange)
    ON_MESSAGE(PBM_SETRANGE32, OnSetRange32)
    END_MESSAGE_MAP()

    COLORREF CTextProgressCtrl::SetForeColour(COLORREF col)
    {
    COLORREF color;

    color=m_colFore;
    m_colFore = col;
    return m_colFore;
    }

    COLORREF CTextProgressCtrl::SetBkColour(COLORREF col)
    {
    COLORREF color;

    color=m_colFore;
    m_colBk = col;
    return color;
    }

    void CTextProgressCtrl::GetRange(int& nLower, int& nUpper)
    {
    nLower=m_nMin;
    nUpper=m_nMax;
    }
    void CTextProgressCtrl::SetRange(short nLower, short nUpper)
    {
    m_nMax = nUpper;
    m_nMin = nLower;
    }
    void CTextProgressCtrl::SetRange32(int nLower, int nUpper)
    {
    m_nMax = nUpper;
    m_nMin = nLower;
    }

    LRESULT CTextProgressCtrl::OnSetStep(WPARAM wParam, LPARAM lParam)
    { return SetStep(wParam);}
    LRESULT CTextProgressCtrl::OnStepIt(WPARAM wParam, LPARAM lParam)
    { return StepIt();}
    LRESULT CTextProgressCtrl::OnGetPos(WPARAM wParam, LPARAM lParam)
    { return GetPos();}
    LRESULT CTextProgressCtrl::OnSetPos(WPARAM wParam, LPARAM lParam)
    { return SetPos(wParam);}
    LRESULT CTextProgressCtrl::OnDeltaPos(WPARAM wParam, LPARAM lParam)
    { return OffsetPos(wParam);}
    LRESULT CTextProgressCtrl::OnSetBarColor(WPARAM wParam, LPARAM lParam)
    { return SetForeColour((COLORREF)lParam);}
    LRESULT CTextProgressCtrl::OnSetBkColor(WPARAM wParam, LPARAM lParam)
    { return SetBkColour((COLORREF)lParam);}
    LRESULT CTextProgressCtrl::OnGetRange(WPARAM wParam, LPARAM lParam)
    {
    int nLower,nUpper;

    GetRange(nLower,nUpper);
    if(lParam!=NULL)
    {
    ((PBRANGE *)lParam)->iLow=nLower;
    ((PBRANGE *)lParam)->iHigh=nUpper;
    }
    if(wParam)
    return nLower;
    else
    return nUpper;
    }
    LRESULT CTextProgressCtrl::OnSetRange(WPARAM wParam, LPARAM lParam)
    {
    WORD wLow,wHigh;

    wLow=m_nMin;
    wHigh=m_nMax;
    SetRange(LOWORD(lParam),HIWORD(lParam));
    return MAKELRESULT(wLow,wHigh);
    }
    LRESULT CTextProgressCtrl::OnSetRange32(WPARAM wParam, LPARAM lParam)
    {
    int nLow,nHigh;

    nLow=m_nMin;
    nHigh=m_nMax;
    SetRange32((int)wParam,(int)lParam);
    return MAKELRESULT(LOWORD(nLow),LOWORD(nHigh));
    }

    Reply
  • Vertical progress bar text support

    Posted by Legacy on 10/04/2001 12:00am

    Originally posted by: Roger Allen

    I implemented the vertical text for the progress bar. New OnPaint is:
    
    

    [ccode]
    void CTextProgressCtrl::OnPaint()
    {
    if (m_nMin >= m_nMax)
    return;

    CRect LeftRect, RightRect, ClientRect;
    GetClientRect(ClientRect);

    double Fraction = (double)(m_nPos - m_nMin) / ((double)(m_nMax - m_nMin));

    CPaintDC PaintDC(this); // device context for painting
    CMemDC dc(&PaintDC);
    //CPaintDC dc(this); // device context for painting (if not double buffering)

    LeftRect = RightRect = ClientRect;

    // KK - 980419 Added vertical control check
    //
    if (GetStyle() & PBS_VERTICAL)
    {
    LeftRect.top = LeftRect.bottom + (int)((LeftRect.top - LeftRect.bottom)*Fraction);
    RightRect.bottom = LeftRect.top;
    }
    else
    {
    LeftRect.right = LeftRect.left + (int)((LeftRect.right - LeftRect.left)*Fraction);
    RightRect.left = LeftRect.right;
    }
    //LeftRect.right = LeftRect.left + (int)((LeftRect.right - LeftRect.left)*Fraction);
    dc.FillSolidRect(LeftRect, m_colFore);

    //RightRect.left = LeftRect.right;
    dc.FillSolidRect(RightRect, m_colBk);

    if (m_bShowText)
    {
    // RIA : Support for rotated text in vertical scroll bar
    CFont font ;
    LOGFONT lf ;
    CFont* pOldFont ;

    // need to use our own font
    memset(&lf, 0, sizeof(LOGFONT)) ;
    lf.lfHeight = -11 ;
    lf.lfWidth = 0 ;
    lf.lfWeight = FW_NORMAL ;
    strcpy(lf.lfFaceName, "Arial") ;

    if (GetStyle() & PBS_VERTICAL)
    {
    lf.lfOrientation = 900 ; // rotate 90'
    lf.lfEscapement = 900 ; // rotate 90'
    }
    font.CreateFontIndirect(&lf) ;
    pOldFont = (CFont*)dc.SelectObject(&font) ;
    CString str;
    if (m_strText.GetLength())
    str = m_strText;
    else
    str.Format("%d%%", (int)(Fraction*100.0));

    dc.SetBkMode(TRANSPARENT);

    CRgn rgn;
    rgn.CreateRectRgn(LeftRect.left, LeftRect.top, LeftRect.right, LeftRect.bottom);
    dc.SelectClipRgn(&rgn);
    dc.SetTextColor(m_colTextBk);

    if (GetStyle() & PBS_VERTICAL)
    {
    // have to use TextOut with a rotated font, else text not positioned in "centre" correctly
    CSize size = dc.GetTextExtent(str) ;
    CRect rect ;
    GetWindowRect(&rect) ;
    dc.TextOut((rect.Width() - size.cy) / 2, rect.Height() - (rect.Height() - size.cx) / 2, str) ;
    rgn.DeleteObject();
    rgn.CreateRectRgn(RightRect.left, RightRect.top, RightRect.right, RightRect.bottom);
    dc.SelectClipRgn(&rgn);
    dc.SetTextColor(m_colTextFore);
    dc.TextOut((rect.Width() - size.cy) / 2, rect.Height() - (rect.Height() - size.cx) / 2, str) ;
    }
    else
    {
    dc.DrawText(str, ClientRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    rgn.DeleteObject();
    rgn.CreateRectRgn(RightRect.left, RightRect.top, RightRect.right, RightRect.bottom);
    dc.SelectClipRgn(&rgn);
    dc.SetTextColor(m_colTextFore);
    dc.DrawText(str, ClientRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    }
    dc.SelectObject(pOldFont) ; // restore original DC font
    }
    }
    [/ccode]

    Reply
  • Progress bar with file open action...

    Posted by Legacy on 05/10/2001 12:00am

    Originally posted by: Bruce Sohn

    The code gives me lots of help.
    I want to use the source to apply to such as 'file open' action.
    If I open some file(text file, etc.), the progress bar will start increase in proportion to the file size.
    The larger file size, the slower its increasing speed.

    The progress bar code with 'file open' action will be needed. Instead of 'file open' action, any time-consuming action will be included.

    Go for it!

    Reply
  • GetPos() broken just like GetRange()

    Posted by Legacy on 03/20/2000 12:00am

    Originally posted by: David Grigsby

    Similar to the problem already noted with GetRange(), 
    
    GetPos() must be overridden to return the local m_nPos member.
    If you don't do this, GetPos() will always return 0.

    Reply
  • How can i change the text font?

    Posted by Legacy on 06/11/1999 12:00am

    Originally posted by: Leigh

    How can i change the text font size and style?

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • It's time high-level executives and IT compliance officers recognize and acknowledge the danger of malicious insiders, an increased attack surface and the potential for breaches caused by employee error or negligence. See why there is extra emphasis on insider threats.

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds