Click here to Skip to main content
Click here to Skip to main content

Enhanced Progress Bar Control

By , 11 Jun 2002
 

You can find the latest version and some other code on my Home Page.

Sample Image - ProgressCtrlX.gif

Introduction

In this article I want to introduce an enhanced ProgressBar control. I collected some ideas from articles on CodeGuru and CodeProject, added some ideas of my own and developed this control. I tried to develop it in the most common, flexible and extensible way. From version 1.3 the control is separated into 3 different classes: CGradient -> CProgress -> CProgressCtrlX. Class CGradient encapsulates gradient drawing functionality. CProgress is a non-window version of the progress control. It supports nearly all the functionality of the progress bar and can be used separately. CProgressCtrlX is a MFC progress bar based control that is also derived from CProgress.

Features:

  • Filling with gradient colors
  • Multi-color gradient (unlimited number of colors)
  • Rubber gradient
  • Filling with brush for background and progress indicator (overrides color settings)
  • Text on bar
  • Dual color for text
  • Any angle text rotation (PBT_ANY_ANGLE) or 0-90-180-270 degree text rotation (w/o PBT_ANY_ANGLE)
  • Text alignment (right, left, top, bottom, centered, vertical centered)
  • Font settings support
  • Formatted text (can show percent, position or plain text)
  • Text tied to progress indicator
  • Support for vertical oriented control
  • Reverse mode
  • Snake mode
  • Borders
  • Shaped mode (Use CRgnX from sample to create rgn from bitmap and text)
  • ToolTip with text formatting
  • Palette support for 256 colors mode (optional)
  • Gradient Animation and Stretching
  • ...........

Advanced Interface:

Text Alignment (to set text alignment styles use SetTextAlign)

	#define PBS_LEFT                 0x0010L
	#define PBS_RIGHT                0x0020L
	#define PBS_CENTER               0x0030L
	#define PBS_TOP                  0x0040L
	#define PBS_BOTTOM               0x0080L
	#define PBS_VCENTER              0x00C0L

Text Format (to set text format use SetTextFormat and HideText):

	#define PBS_SHOW_PERCENT         0x0100
	#define PBS_SHOW_POSITION        0x0200
	#define PBS_SHOW_TEXTONLY        0x0300

Control Styles (use ModifyBarStyle or appropriated functions):

	    
	#define PBS_TIED_TEXT        0x1000 
	#define PBS_RUBBER_BAR       0x2000 
	#define	PBS_REVERSE          0x4000
	#define PBS_SNAKE            0x8000

Advanced functionality:

 
CGradient:
	void SetStretchGradient(float flStretchFactor = 1); // useful for animation
	float GetStretchGradient();

	void SetGradientColors(COLORREF clrStart, COLORREF clrEnd); void
	GetGradientColors(COLORREF& clrStart, COLORREF&  clrEnd);

	void SetGradientColorsX(int nCount, COLORREF clrFirst, COLORREF  clrNext, ...); 
	const CDWordArray& GetGradientColorsX();
	void AddColor(COLORREF clr);

	void SetCreatePalette(BOOL fCreate =TRUE); 
	BOOL GetCreatePalette();
	CPalette& GetPalette(); 
	    
CProgress:

	void SetBarBrush(CBrush* pbrBar);
	CBrush* GetBarBrush();

	void SetBkColor(COLORREF clrBk);
	COLORREF GetBkColor();

	void SetBkBrush(CBrush* pbrBk);
	CBrush* GetBkBrush();

	void SetTextColor(COLORREF clrTextOnBar, COLORREF clrTextOnBk = -1);
	COLORREF GetTextColor();
	COLORREF GetTextColorOnBk();

	void SetShowPercent(BOOL fShowPercent = TRUE);
	BOOL GetShowPercent();

	void SetTextAlign(DWORD dwStyle);
	DWORD GetTextAlign();

	void SetTextFormat(LPCTSTR szFormat, DWORD ffFormat = PBS_SHOW_TEXTONLY);
	void HideText();

	void SetTiedText(BOOL fTiedText = TRUE);
	BOOL GetTiedText();

	void SetRubberBar(BOOL fRubberBar = TRUE);
	BOOL GetRubberBar();

	void SetReverse(BOOL fReverse = TRUE);
	BOOL GetReverse();

	void SetSnake(BOOL fSnake = TRUE);
	BOOL GetSnake();

	void SetSnakeTail(int nTailSize);
	int  GetSnakeTail();

	void SetBorders(const CRect& rcBorders);
	const CRect& GetBorders();

	void SetShape(HBITMAP hBmp, COLORREF clrTransparent = 0);

	void SetRange(int nLower, int nUpper);
	void GetRange(int& nLower, int& nUpper);

	int GetPos() {return m_nPos;}
	int SetPos(int nPos);

	int OffsetPos(int nIncrement);

	int SetStep(int nStep);

	int StepIt();

	void SetFont(CFont* pFont);
	CFont* GetFont();

	void Draw(CDC* pDC, CRect rcDraw, BOOL fSkipDCCache = FALSE);

	virtual DWORD GetBarStyle();
	virtual void ModifyBarStyle(DWORD dwRemove, DWORD dwAdd);

	void Animate(int nStep);
	void ResetAnimation();
CProgressCtrlX:

	void SetTooltipFormat (LPCTSTR lpszToolTipText, DWORD fFormat = PBS_SHOW_TEXTONLY);
	LPCTSTR GetTooltipText();
	void HideTooltip();
	
	void RunSnake(int nMsPerStep);
	void StopSnake();

	void RunAnimation(int nMsPerStep, int nStep);
	void StopAnimation();

You can use:

  • SetFont() - to set font and rotation(Escapement) of the text
  • SetStyle(), ModifyStyle(), SetBarStyle(), ModifyBarStyle() - to change styles of control
  • Any functionality of base class CProgressCtrl

See Test Project for additional information on usage.

Notes

The best views and performance is got on HighColor(15/16 bit) and TrueColor(24/32 bit) resolutions. Control also supports 256 and 16 color modes. However, in 16 colors mode you cannot use gradient, and in 256 colors mode the control works slower because of usage of CreateSolidBrush/FillRect instead of FillSolidRect.

If you want rotate text to any angle - define PBT_ANY_ANGLE and recompile control.

Control is part of UIBits.dll and independent usage requires additional files: DrawGdiX.h, MemDC.h

History

January 21, 2001 - version 1.4

  • Gradient Animation and stretching added
  • Fixed some bugs from previous version

January 10, 2001 - version 1.3

  • Code separated to three classes CGradient, CProgress and CProgressCtrlX
  • Added tooltips with text formatting
  • Added self running snake
  • Added palette support for 256 colors mode
  • Added shaped style drawing

September 20, 2000 - version 1.2

  • Added support for "Any angle text rotation"
    (define PBT_ANY_ANGLE and set font with appropriated angle)
  • Added text alignment
  • Added possibility to format text (via virtual function FormatText())
    e.g. you can show percent as decimal fraction instead of integer
  • Some code improvements

August 2, 2000 - version 1.1

  • Added multi-color gradient
  • Added filling with brush for background and bar (overrides color settings)
  • Added borders attribute
  • Added vertical text support
  • Added snake mode
  • Added reverse mode
  • Added dual color for text
  • Added text formatting
  • Added tied mode for text and rubber bar mode
  • Added support for vertical oriented control (PBS_VERTICAL)

June 5, 2000 - version 1.0

You can find the latest version and some other code on my Home Page.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Yury Goltsman
Software Developer (Senior)
Israel Israel
Member
Yury is Software Engineer since 1988.
His programming experience includes C#/VB.NET, WPF, C/C++(MFC/STL), Borland Delphi & C++ (VCL), JavaScript, HTML, CSS, XML, SQL, VB6, DirectX, Flash.
He has worked on PCs (DOS/Win3.1-Vista) and PocketPCs (WinCE).
 
Yury was born in Ukraine, but currently based in Jerusalem.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGreat progress bar and scles on itmemberGeorge papas20 Aug '10 - 3:27 
HI ,
 
this is a great tool, but i have acouple of questions.
1/ how do you use it in c# project?
2/ Can you ad a scale lines for mas, min and a series based on a number eg 10 so you have 10 scale line.
 
thanks george
GeneralRe: Great progress bar and scles on itmemberYury Goltsman21 Aug '10 - 20:59 
Thanks.
I don't see a simple way to use it under C#, because it built for MFC of VS6.0
I don't support this control, because I don't use MFC for about 8 years and the control is stable enough.
You can take source code and extend it according to your requirements. From other side you can use WPF to create similar control in minutes and use it under Win Forms.
If you start new application I recommend create it on WPF from beginning.
GeneralA little problem under Windows XP theme [modified]memberchocm12 Jan '09 - 0:04 
Thank you very much for your great ProgressCtlrX( v1.41 ) control, it's very powerful.
 
I have tried to add the following lines into stdafx.h in your ProgressCtrlX_demo.zip sample to enable Windows XP theme, after building, the progress bar showed correctly under the Windows classical, but restarting the demo executable under the Windows XP theme, the border of the progress bar didn't show.
 
[code]
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
 
[/code]
 
modified on Monday, January 12, 2009 6:12 AM

GeneralRe: A little problem under Windows XP themememberYury Goltsman12 Jan '09 - 2:18 
You are right. The control was developed on w2k and not updated for XP themes. It doesn't draw frame, instead it uses default border of base progress bar, which draws border in non-client area. Themed control doesn't have this frame and so we have the problem. You can add frame painting inside the CProgress::Draw() in case theme is enabled and place changes here in comment. Thanks.
 
something like this:
info.pDC->FrameRect(&info.rcClient, m_pbrBorder); //add brush to interface
info.rcClient.DeflateRect(1,1);
// fill background
...
GeneralSome questionsmemberElClassico16 Nov '07 - 11:55 
I'm using a progress bar to indicate the completed number of runs. The maximum number of runs is user specified (and is initially used for the upper range of the progress bar), however as we complete runs, we can estimate a lower number of required runs. As more and more runs are done and we converge to a solution, the estimated required number of runs changes. I originally implemented this so that the upper range changes to reflect the estimated required number of runs. However, I think a requirement is going to be imposed that the progress can't go backwards, which is certainly possible with my current implementation since the estimated number of runs can increase. I was thinking instead I could leave upper range to the maximum allowable number or runs, and then indicate graphically where the estimated number of runs is on the progress bar. To do this I was thinking I could make the progress bar transparent, and draw a second progress behind it which shows the estimated number of runs. (This would look blue indicates progress, white between completed and estimated, and grey between estimated and maximum) However, it appears the MFC CProgressCtrl won't become transparent. Any ideas on how to implement this using CProgressCtrl, the Enhanced Progress Bar Control or otherwise?
GeneralRe: Some questionsmemberYury Goltsman18 Nov '07 - 9:17 
No, I have no idea how to make it transparent, but you have access to whole source code of the bar and you may draw another progress part inside. I think it should not be too difficult.
 
Regards
QuestionRubber bar?memberElClassico16 Nov '07 - 11:48 
What does rubber bar do? I tried looking at the code to figure it out, and using the sample project, but I don't see any difference.

AnswerRe: Rubber bar?memberYury Goltsman18 Nov '07 - 9:06 
Actually rubber bar is rubber gradient. Open Demo, choose "Multi color gradient", press "Run" and then select "Rubber bar". Compare with previous state. This option bindes gradient fill to progress part of bar. It looks like progress stretched like rubber.
GeneralWorks greatmembercopernican20 Sep '06 - 11:49 
Even without the fancy formatting options, it's possibly the easiest way to get rid of flicker.
QuestionHow to refresh the updated position?? [modified]memberpavanbabut18 Jul '06 - 7:25 
This tool is nice and cool to use. But how can I refresh the updated position on the bar. I am calling function StepIt() and also tried using SetPos() within my loop where I would like to update. But all it does is, showing 100% at the end of the loop, till then it just sits at 0%. Is there any other command to update the data??
When I am callig out of the loop it is working/updating fine, but not within the loop ....
 
//m_nSIZE = 240000000
while(..xyz..)
{
....
i+=4;
if (i%(m_nSIZE/100) == 0)
m_nLProgress.StepIt();
}
 
thanks,
-Pavan
 

 

-- modified at 13:25 Tuesday 18th July, 2006

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 12 Jun 2002
Article Copyright 2001 by Yury Goltsman
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid