Windows Controls: The Progress Bar


Introduction to Progress Bars



A progress bar is a control that displays (small) rectangles that are each filled with a color. These (small) rectangles are separate but adjacent each other so that, as they display, they produce a bar. To have the effect of a progress bar, not all these rectangles display at the same time. Instead, a numeric value specifies how many of these (small) rectangles can display at one time.

There are two types of progress bars and various characteristics they can have. For example, although most progress bars are horizontal, the control can assume a vertical orientation:

Progress Bars

As mentioned already, a progress bar is made of small colored rectangles. These rectangles can display distinctively from each other although they are always adjacent. The programmer can also specify what color would fill the small rectangles. To make it less confusing, all of the small rectangles display in the same color. The small rectangles can be "glued" to produce a smooth effect, in which case they would not appear distinct.

Practical LearningPractical Learning: Introducing Progress Bars

  1. To start a new project, on the main menu, click File -> New -> VCL Forms Application- C++Builder
  2. In the Object Inspector, change the following properties of the form:
    Caption: Progressive Clock
    Name: frmMain
    Position: poScreenCenter

Creating a Progress Bar

To support progress bar, the VCL provides the TProgressBar class. The TProgressBar class is derived from TWinControl:

TProgressBar Inheritance

In the Tool Palette, the progress bar is represented by the TProgressBar icon. Therefore, to visually add a progress bar to your application, from the Win32 section of the Tool Palette, click the TProgressBar button ProgressBar and click the form.

Practical LearningPractical Learning: Creating Progress Bars

  1. Design the form as follows:
    Progress Clock
    Control Caption Kind Name
    TLabel Label Hours:    
    TProgressBar ProgressBar     pgrHours
    TLabel Label 00   lblHours
    TLabel Label Minutes:    
    TProgressBar ProgressBar     pgrMinutes
    TLabel Label 00   lblMinutes
    TLabel Label Seconds:    
    TProgressBar ProgressBar     pgrSeconds
    TLabel Label 00   lblSeconds
    TBitBtn Label   bkClose  

Characteristics of Progress Bars


The Orientation of a Progress Bar

By default, a newly added progress bar assumes a horizontal position. This aspect is controlled by the Orientation property which is a TProgressBarOrientation enumeration defined as follows:

enum TProgressBarOrientation { pbHorizontal, pbVertical };

The default value of the Orientation property is pbHorizontal. This is equivalent to not specifying an orientation when programmatically creating the control using either the VCL or the Win32 libraries. If you want the progress bar to appear vertical, at design time, set the Orientation value to pbVertical. If you are creating the progress bar using the Win32 library, you must OR the PBS_VERTICAL style. Here is an example:

void __fastcall TForm1::FormCreate(TObject *Sender)
	CreateWindowEx(0, PROGRESS_CLASS, NULL,
		       20, 20, 18, 170,
		       Handle, NULL, HInstance, NULL);

The Smoothness of a Progress Bar

As mentioned already, a progress bar appears as a series of small adjacent rectangles. By default, these rectangles display distinctively. If on the other hand you want to "glue" them and produce a smooth bar, use the Smooth Boolean property:

__property bool Smooth = {read=FSmooth,write=SetSmooth};

Its default value is false, making the small rectangles separate. If you set this property to true, the bar would appear continuous. If creating the control using the CreateWindow() or CreateWindowEx() Win32 function, you can OR the PBS_SMOOTH style.

To display its small rectangles or the smooth bar, the progress bar uses a preset color, which is usually blue. If you prefer to use a different color, call the SendMessage() function with the PBM_SETBARCOLOR message. The syntax you would is:

SendMessage(HWND hWnd,
	    wParam = 0,
	    lParam = (LPARAM)(COLORREF)clrBar;

As you can see from this syntax, the wParam argument is not used and must be passed as 0. The desired color for the bar is specified using the lParam argument. Here is an example:

void __fastcall TForm1::FormCreate(TObject *Sender)
	SendMessage(ProgressBar1->Handle, PBM_SETBARCOLOR, 0, clRed);

Practical LearningPractical Learning: Smoothing a Progress Bar

  1. On the form, click one of the progress bars
  2. In the Object Inspector, click the Smooth check box to make it True
  3. Do the same for the other two progress bars

The Values of a Progress Bar

To show its effect, the progress bar draws its small rectangles on a bar. These small shapes are from a starting position to an end. This means that the progress bar uses a range of values. This range is controlled by the Min and the Max properties:

__property int Min = {read=GetMin,write=SetMin};
__property int Max = {read=GetMax,write=SetMax};

Their default values are 0 and 100 respectively. At design time, you can set them using the limits of an unsigned short integer, that is, from 0 to 65,535. In Win32, the range of values of a progress bar is set using the PBM_SETRANGE message using the following syntax:

SendMessage(HWND hWnd,
	    wParam = 0,
	    lParam = MAKELPARAM(nMinRange, nMaxRange);

Alternative, you can send the PBM_SETRANGE32 message to set the range of the progress bar. This time, the syntax used would be:

SendMessage(HWND hWnd,
	    wParam = (WPARAM)(int) iLowLim,
	    lParam = (LPARAM)(int) iHighLim);

For a horizontal progress bar, the small rectangles are drawn from left to right. For a vertical progress bar, the small rectangles are drawn from bottom to top. At one particular time, the most top or the most right rectangle of a progress bar is referred to as its position. At design time, to set a specific position for the control, change the value of the Position property whose default is 0. The position must always be between the Min and Max values. If you set it to a value lower than the Min, the Object Inspector would reset it to Min. In the same way, if it is set to a value higher than Max, it would be reset to the Max value. At run time, you can assign the desired value to the Position property. Once again, avoid specifying a value that is out of range.

Practical LearningPractical Learning: Setting the Maximum Value of a Progress Bar

  1. On the form, click the top progress bar (corresponding to the hours)
  2. In the Object Inspector, click Max, type 23 and press Enter
  3. On the form, click the middle progress bar (corresponding to the minutes)
  4. Press and hold Shift
  5. Click the bottom progress bar
  6. Release Shift
  7. In the Object Inspector, click Max, type 59 and press Enter

The Step of a Progress Bar

Because a progress bar is usually meant to indicate the progress of an activity, when drawing its small rectangles, it increases its current position in order to draw the next rectangle, except if the control is reset. The number of units that the control must increase value is controlled by the Step property:

__property int Step = {read=FStep,write=SetStep};

By default, it is set to 1. Otherwise, you can set it to a different value of your choice.

Practical LearningPractical Learning: Setting the Step of a Progress Bar

  1. On the form, click the top progress bar (corresponding to the hours)
  2. Press and hold Shift
  3. On the form, click the middle progress bar (corresponding to the minutes)
  4. Click the bottom progress bar
  5. Release Shift
  6. In the Object Inspector, click Step, type 1 and press Enter

The Position of a Progress Bar

The ProgressBar control is based on the TProgressBar class. Like every VCL class, it is equipped with a constructor that can be used to dynamically create the control.

We have seen that a progress bar implements its behavior by drawing small adjacent rectangles. This control does not know and does not decide when to draw these indicators. Therefore, after creating a progress bar, you must provide a means of changing its value, that is, a way to increment its position. Although it is usually used to show the evolution of a task, it does not actually have an internal mechanism to monitor such an activity. Another control is usually used to trigger this. Nevertheless, when the value of a progress bar changes, the control refers to the Step property to increment its Position. Based on this Step value, when it is time to increment, the progress bar calls its StepIt() method. Its syntax is:

void __fastcall StepIt(void);

If you want to increase the progress barís position by a value other than Step, you can call the StepBy() method. Its syntax is:

void __fastcall StepBy(int Delta);

Pass the desired incremental value as the Delta argument.

Practical LearningPractical Learning: Implementing Progress Bars

  1. On the form, double-click the TTimer1 timer to access its OnTimer event
  2. Implement it as follows:
    void __fastcall TfrmProgress::Timer1Timer(TObject *Sender)
    	// Get the current time
    	TDateTime CurTime = TDateTime::CurrentTime();
    	unsigned short Hours, Minutes, Seconds, Milliseconds;
    	// Retrieve the hour, minute, and second values of the current time
    	CurTime.DecodeTime(&Hours, &Minutes, &Seconds, &Milliseconds);
    	// Draw the progress boxes based on the values of the time
    	pgrHours->Position = Hours;
    	pgrMinutes->Position = Minutes;
    	pgrSeconds->Position = Seconds;
    	// Display the values in the corresponding labels
    	lblHours->Caption   = UnicodeString(Hours);
    	lblMinutes->Caption = UnicodeString(Minutes);
    	lblSeconds->Caption = UnicodeString(Seconds);
  3. To execute the application, on the main menu, click Run -> Run
    Progressive Clock
  4. After using the form, close it and return to your programming environment

Home Copyright © 2010-2016, FunctionX