Gradient Progress control
Download Source Code
and Example
Development Environment: VC5, 95
This is a simple class to display a gradient fill progress control. It works just like the normal progress control. The main enhancements are that you can customize the colors and toggle the percentage caption's visibility.
The control can be incorporated into a project like any other CProgressCtrl derived control. Either create the control manually, subclass an existing CProgressCtrl, or use ClassWizard to DDX_control it. The actual code for the progress control is located in GradientProgressCtrl.h and GradientProgressCtrl.cpp. I haven't fully tested it's robustness, although I don't suspect that it will fail miserably. Most of the work happens in the DrawGradient(...) function, which also uses Keith Rule's MemDC class. The sample project also uses Chris Maunder's ColourPicker. Both of these classes are included in the sample project and can be downloaded elsewhere at this site.
It is derived from CProgressCtrl so all standard CProgressCtrl functions are available. Additional functions are listed below.
I hope someone gives it a good home :). Please let me know of any problems or improvements. Thanks and good luck.
Member Set Functions
void SetTextColor(COLORREF color) // Set the percentage text color void SetBkColor(COLORREF color) // Set background color void SetStartColor(COLORREF color) // Set starting color void SetEndColor(COLORREF color) // Set ending color void ShowPercent(BOOL bShowPercent = TRUE) // Show the percent caption?
Member Get Functions
COLORREF GetTextColor(void) COLORREF GetBkColor(void) COLORREF GetStartColor(void) COLORREF GetEndColor(void)
Last updated: 18 May 1998

Comments
GetPercent of CGradientProgressCtrl
Posted by Legacy on 12/16/2003 12:00amOriginally posted by: Micket
CString CGradientProgressCtrl::GetPercent()
{
CString percent;
percent.Format("%.0f%%", 100.0f*(float)m_nCurrentPosition/(float)m_nUpper);
return percent;
Reply}
Error using OffsetPos
Posted by Legacy on 03/23/2001 12:00amOriginally posted by: Daniel Bayer
Be aware of using OffsetPos instead of SetPos with this implementation of CGradiantProgressCtrl. Bugfix should be really simple, but i used the easy way an replaced OffsetPos by using SetPos. Thats it folks! Keep on improving Windows GUI and bring pleasure to the eyes of the world!
ReplyVertical?
Posted by Legacy on 07/27/1999 12:00amOriginally posted by: john
Anyway to make it work vertical also?
ReplyUpdate To the code that outputs the text
Posted by Legacy on 07/15/1999 12:00amOriginally posted by: Murali Soundararajan
This code should replace the "Show percent indicator if needed" code in CGradientProgressCtrl::OnPaint(). It draws the text using colors that force the text to stand out regardless of the Gradient start & stop you choose.
if (m_bShowPercent)
{
CMemDC memDC(&dc);
CDC dcMask;
CDC dc2;
// Create a place to work on our inverted text...
VERIFY(dcMask.CreateCompatibleDC(&dc));
VERIFY(dc2.CreateCompatibleDC(&dc));
// Certain types of bitmap operations require WORD aligned buffers
CRect rectEven;
::SetRect(&rectEven,
0, // Upper left X
0, // Upper left Y
((rectClient.Width()+7)*16)/16-1, // Lower right X
((rectClient.Height()+7)*16)/16-1); // Lower right Y
// Create the text mask
CBitmap bmShadow;
VERIFY(bmShadow.CreateBitmap( rectEven.Width(),rectEven.Height(), 1, 1, NULL ) );
CBitmap* pOldBitmap = dcMask.SelectObject(&bmShadow);
CString percent;
if (m_strOutput.IsEmpty())
percent.Format("%3.0f %%", 100.0f*(float)nDrawPosition/(float)m_nUpper);
else
percent = m_strOutput;
RECT rectFill; // Rectangle for filling band
::SetRect(&rectFill,
0, // Upper left X
0, // Upper left Y
rectClient.Width()-1, // Lower right X
rectClient.Height())-1; // Lower right Y
// Blank the mask bitmap
VERIFY(dcMask.BitBlt(0,0,rectEven.Width(),rectEven.Height(),NULL,rectClient.top,rectClient.left,BLACKNESS));
// Print The text in white text on the mask
dcMask.SetTextColor(RGB(255,255,255));
dcMask.SetBkMode(TRANSPARENT);
dcMask.DrawText(percent, &rectFill, DT_VCENTER | DT_CENTER | DT_SINGLELINE); // write out text
// Create the invert color
CBitmap bmInvertColor;
bmInvertColor.CreateCompatibleBitmap(&dc,rectEven.Width(), rectEven.Height());
CBitmap* pOldBitmapDC2 = dc2.SelectObject(&bmInvertColor);
// copy get a copy of the screen
VERIFY(dc2.BitBlt(0,0,rectEven.Width(),rectEven.Height(),&dc,rectClient.top,rectClient.left,NOTSRCCOPY));
// invert the colors in the copy
// taken care of in NOTSRCCOPY VERIFY(dc2.BitBlt(0,0,rectClient.Width(),rectClient.Height(),NULL,0,0,DSTINVERT));
// AND the "White" text mask to the Invert Colors => this produces our inverted color text
VERIFY(dc2.BitBlt(0,0,rectEven.Width(),rectEven.Height(),&dcMask,0,0,SRCAND));
// Now invert the text mask
VERIFY(dcMask.BitBlt(0,0,rectEven.Width(),rectEven.Height(),NULL,0,0,DSTINVERT));
// Prepare screen - Apply inverted text mask to screen, ie erase data on screen we are going to replace
VERIFY(memDC.BitBlt(rectClient.top,rectClient.left,rectClient.Width(),rectClient.Height(),&dcMask,0,0,SRCAND));
// Now fill in the area we cleared using the "inverted text mask" by copying "inverted color text" to the screen
VERIFY(memDC.BitBlt(rectClient.top,rectClient.left,rectClient.Width(),rectClient.Height(),&dc2,0,0,SRCPAINT));
dcMask.SelectObject(pOldBitmap);
ReplydcMask.DeleteDC();
dc2.SelectObject(pOldBitmapDC2);
dc2.DeleteDC();
}
Percent string badly computed !
Posted by Legacy on 05/10/1999 12:00amOriginally posted by: Fabrice GIRARDOT
The displayed percent string is badly evaluated.
To fix it, use such formula :
float percent = 100.0f;
percent *= (float)(m_nCurrentPosition-m_nLower);
percent /= (float)(m_nUpper-m_nLower);
It may display value <0 or >100 if out of range !
Anyway, this is a *GREAT* control !
Thanks a lot.
Regards.
ReplyFabrice.
Bug fix for Gradient Progress Control
Posted by Legacy on 04/08/1999 12:00amOriginally posted by: Rajesh Bobade
ReplyVC 6 - SetRange32
Posted by Legacy on 02/23/1999 12:00amOriginally posted by: Greg
I thought I would point out in VC6 the CProgressCtrl has a SetRange and SetRange32 function. SetRange32 must have been added between VC5 and VC6, so you will need to override this function in the CGradientProgressCtrl class.
Otherwise, this class works great! Thanks.
ReplyAn Oddity
Posted by Legacy on 02/18/1999 12:00amOriginally posted by: Rick York
I noticed an oddity with this control. At least, I think
it's oddity - it is apparently by design. When the value
of the progress hits its maximum the bar goes away.
The reason this seems to be an oddity is that the standard
progress bar does not exhibit this behavior.
Luckily the fix for this is simple : on line 83 change
the greater than or equal to just a greater than.
It could be argued that if the value exceeds the maximum
then just consider it to be AT the maximum but that is
probably picking at nits.
Nit-picking aside, this is a very nice control, thanks a lot !
ReplyI am using it in an app I hope to be posting here soon :)