How to create a smooth ProgressBar in Visual C++ 2005 or in Visual C++ .NET (816195)
The information in this article applies to:
- Microsoft Visual C++ 2005 Express Edition
- Microsoft Visual C++ .NET (2003)
- Microsoft .NET Framework 1.1
For a Microsoft Visual Basic .NET version of this
article, see
323088. For a Microsoft Visual C# .NET version of this
article, see
323116. This article refers to the following
Microsoft .NET Framework Class Library namespaces:
- System::ComponentModel
- System::Collections
- System::Windows::Forms
- System::Data
- System::Drawing
IN THIS TASKSUMMARYThis article describes how to create a simple, custom
UserControl class to create a smooth, scrolling ProgressBar control. In earlier versions of the ProgressBar control, such as the version that is provided with the Microsoft
Windows Common Controls ActiveX control, you can view the progress in two
different views. To control these views, you use the Scrolling property that includes standard and smooth settings. Smooth
scrolling produces a solid block of color that represents the progress, and
standard scrolling appears segmented and is made up of a series of small blocks
or rectangles. The ProgressBar control that is included with
Microsoft Visual C++ 2005 or with Microsoft Visual C++ .NET supports only the standard setting. The
sample code in this article describes how to create a control that supports the
following properties:
- Minimum: This property obtains or sets the lower value for the range of
valid values for progress. The default value of this property is zero (0); you
cannot set this property to a negative value.
- Maximum: This property obtains or sets the upper value for the range of
valid values for progress. The default value of this property is
100.
- Value: This property obtains or sets the current level of progress. The
value must be in the range that the Minimum and the Maximum properties
define.
- ProgressBarColor: This property obtains or sets the color of the progress
bar.
Back to the
topRequirementsThe
following list outlines the recommended hardware, software, network
infrastructure, and service packs that you need: - Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET 2003
- Microsoft .NET Framework 1.1 or later
This
article assumes that you are familiar with the following topics:
- Creating controls by using Microsoft Visual C++ 2005 or Microsoft Visual C++ .NET 2003
Back to the
topCreate a custom ProgressBar control- Start Microsoft Visual Studio 2005 or Microsoft Visual Studio .NET 2003.
- On the File menu, point to
New, and then click Project.
- Click Visual
C++ Projects under Project Types, and then click Windows
Control Library (.NET) under Templates.
Note In Visual Studio 2005, click Visual C++ under Project Types, and then click Windows Forms Console Library under Templates. - In the Name box, type
SmoothProgressBar, and then click
OK.
- Typically, you inherit the newly
created UserControl class (SmoothProgressBarControl class) from the ProgressBar class, and then you add the additional functionality to extend the
existing ProgressBar control. However, the ProgressBar class is a sealed class and cannot be inherited. Therefore, you must
build the control from the beginning. To do this, follow these steps:
- On the View menu, click
Code to open the code editor.
- Add the following member variable declarations for
holding the property values to the SmoothProgressBar class before the constructor function.
// Minimum value for progress range
int minimum;
// Maximum value for progress range
int maximum;
// Current progress
int value;
// Color of progress meter
Color progressBarColor; - Add the following code to initialize the member
variables in the constructor function after the InitializeComponent statement.
minimum = 0;
maximum = 100;
value = 0;
progressBarColor = Color::Blue; - Add the following property getter and setter functions
after the InitializeComponent function in the SmoothProgressBarControl class.
public:
__property int get_Minimum()
{
return minimum;
}
__property void set_Minimum(int NewMinimum)
{
// Prevent a negative value.
if (NewMinimum < 0)
{
minimum = 0;
}
// Make sure that the minimum value is never set higher than the maximum value.
if (NewMinimum > maximum)
{
minimum = NewMinimum;
}
// Ensure value is still in range
if (value < minimum)
{
value = minimum;
}
// Invalidate the control to get a repaint.
this->Invalidate();
}
__property int get_Maximum()
{
return maximum;
}
__property void set_Maximum(int NewMaximum)
{
// Make sure that the maximum value is never set lower than the minimum value.
if (NewMaximum < minimum)
{
minimum = NewMaximum;
}
maximum = NewMaximum;
// Make sure that value is still in range.
if (value > maximum)
{
value = maximum;
}
// Invalidate the control to get a repaint.
this->Invalidate();
}
__property int get_Value()
{
return value;
}
__property void set_Value(int NewValue)
{
int oldValue = value;
// Make sure that the value does not stray outside the valid range.
if (NewValue < minimum)
{
value = minimum;
}
else if (NewValue > maximum)
{
value = maximum;
}
else
{
value = NewValue;
}
// Invalidate only the changed area.
float percent;
Rectangle newValueRect = this->ClientRectangle;
Rectangle oldValueRect = this->ClientRectangle;
// Use a new value to calculate the rectangle for progress.
percent = (float)(value - minimum) / (float)(maximum - minimum);
newValueRect.Width = (int)((float)newValueRect.Width * percent);
// Use an old value to calculate the rectangle for progress.
percent = (float)(oldValue - minimum) / (float)(maximum - minimum);
oldValueRect.Width = (int)((float)oldValueRect.Width * percent);
Rectangle updateRect;
// Find only the part of the screen that must be updated.
if (newValueRect.Width > oldValueRect.Width)
{
updateRect.X = oldValueRect.Size.Width;
updateRect.Width = newValueRect.Width - oldValueRect.Width;
}
else
{
updateRect.X = newValueRect.Size.Width;
updateRect.Width = oldValueRect.Width - newValueRect.Width;
}
updateRect.Height = this->Height;
// Invalidate the intersection region only.
this->Invalidate(updateRect);
}
__property Color get_ProgressBarColor()
{
return progressBarColor;
}
__property void set_ProgressBarColor(Color NewColor)
{
progressBarColor = NewColor;
// Invalidate the control to get a repaint.
this->Invalidate();
} Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile the previous code sample.
To add the common language runtime support compiler option in Visual C++ 2005, follow these steps:
- Click Project, and then click <ProjectName> Properties.
Note <ProjectName> is a placeholder for the name of the project. - Expand Configuration Properties, and then click General.
- Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting in the right pane, click Apply, and then click OK.
For more information about the common language runtime support compiler option, visit the following Microsoft Web site: - Add the following code that handles the display of the ProgressBar control after the property getter and setter functions that you added in the previous step.
protected:
void OnResize(EventArgs *e)
{
// Invalidate the control to get a repaint.
this->Invalidate();
}
void OnPaint(PaintEventArgs *e)
{
Graphics *g = e->Graphics;
SolidBrush * brush = new SolidBrush(progressBarColor);
float percent = (float)(value - minimum) / (float)(maximum - minimum);
Rectangle rect = this->ClientRectangle;
// Calculate area for drawing the progress.
rect.Width = (int)((float)rect.Width * percent);
// Draw the progress meter.
g->FillRectangle(brush, rect);
// Draw a three-dimensional border around the control.
Draw3DBorder(g);
// Clean up.
brush->Dispose();
g->Dispose();
}
private:
void Draw3DBorder(Graphics *g)
{
int PenWidth = (int)Pens::White->Width;
g->DrawLine(Pens::DarkGray,
Point(this->ClientRectangle.Left , this->ClientRectangle.Top),
Point((int)(this->ClientRectangle.Width) - PenWidth, this->ClientRectangle.Top));
g->DrawLine(Pens::DarkGray,
Point(this->ClientRectangle.Left, this->ClientRectangle.Top),
Point(this->ClientRectangle.Left, (int)(this->ClientRectangle.Height) - PenWidth));
g->DrawLine(Pens::White,
Point(this->ClientRectangle.Left, (int)(this->ClientRectangle.Height) - PenWidth),
Point((int)(this->ClientRectangle.Width) - PenWidth, (int)(this->ClientRectangle.Height) - PenWidth));
g->DrawLine(Pens::White,
Point((int)(this->ClientRectangle.Width) - PenWidth, this->ClientRectangle.Top),
Point((int)(this->ClientRectangle.Width) - PenWidth, (int)(this->ClientRectangle.Height) - PenWidth));
}
- Press the CTRL+SHIFT+S key combination to save the
project.
- Press the CTRL+SHIFT+B key combination to build the
solution.
This builds the SmoothProgressBarControl UserControl class and creates a dynamic link library (DLL)
file. - On the File menu, click Close
Solution to quit the project.
Back to the
topCreate a sample client application- On the File menu, point to
New, and then click Project.
- Click Visual
C++ Projects under Project Types, and then click Windows
Forms Application (.NET) under Templates.
- In the Name box, type
ProgressBar, and then click
OK.
By default, the Form1 form is
created and opens in Design mode. - To add two instances of the SmoothProgressBarControl control to the form, follow these steps:
- On the Tools menu, click
Add/Remove Toolbox Items.
- On the .NET Framework Components
tab, click Browse, and then locate the SmoothProgressBar.dll file that you created in the Create a custom ProgressBar control section.
- Click OK. Notice that the
SmoothProgressBarControl control is added to the
toolbox.
- Add two instances of
the SmoothProgressBarControl control to Form1.
- Add a Timer control to Form1.
- Right-click the timer1 control that is shown
separately at the bottom of the designer window, and then click
Properties.
- Click the Events button, and
then double-click the Tick event to add a
timer1_Tick event handler to the code.
- Add the following code in the timer1_Tick
event handler.
if (this->smoothProgressBarControl1->Value > 0)
{
this->smoothProgressBarControl1->Value--;
this->smoothProgressBarControl2->Value++;
}
else
{
this->timer1->Enabled = false;
} - On the View menu, click
Designer to switch to Design mode.
- Add a Button control to Form1.
- Double-click button1 to add a
button1_Click event handler to the code.
- Add the following code in the
button1_Click event handler:
this->smoothProgressBarControl1->Value = 100;
this->smoothProgressBarControl2->Value = 0;
this->timer1->Interval = 1;
this->timer1->Enabled = true; - Press the CTRL+SHIFT+S key combination to save the
project.
- Press the CTRL+SHIFT+B key combination to build the
solution.
- Press the CTRL+F5 key combination to run the
project.
- Click button1. Notice that the two
progress indicators display the progress in a smooth manner. One progress
indicator displays the progress in an increasing manner, and the other progress
indicator displays the progress in a decreasing or a countdown manner.
Back to the
topREFERENCESFor more information about the ProgressBar class, visit the following
Microsoft Developer Network (MSDN) Web site: Back to the top
Modification Type: | Major | Last Reviewed: | 12/30/2005 |
---|
Keywords: | kbWindowsForms kbGDI kbForms kbDLL kbCtrl kbControl kbCollections kbHOWTOmaster KB816195 kbAudDeveloper |
---|
|
|
©2004 Microsoft Corporation. All rights reserved.
|
|