Windows Controls: Track Bars


Introduction to Track Bars



A track bar is a Windows control used to slide a small bar or pointer, also called a thumb, along a continuous line. The following dialog box displays two track bars, each between a Low and a High labels:

Microphone Properties

To use the track bar, the user can drag the thumb in one of two directions. This changes the position of the thumb. The user can also click a position along the control line to place the thumb at a desired location. Alternatively, when the track bar has focus, the user can use the arrow keys to move the thumb.

As far as positions are concerned, there are two types of track bars, depending on the orientation: horizontal or vertical:

Track Bar

A track bar is configured with a set of values from a minimum to a maximum. Therefore, the user can make a selection included in that range. Optionally, a track bar can be equipped with small marks called ticks. These can visually guide the user for the available positions of the thumb. A track bar can be used as a progress control to help the user monitor an activity. A track bar also allows the user to specify a value that conforms to a range. When equipped with small indicators, also called ticks, a track bar can be used to control exact values that the user can select in a range, preventing the user from setting just any value.

Practical LearningPractical Learning: Introducing Track Bars

  1. To create a new project, on the main menu, click File -> New -> VCL Forms Application - C++Builder
  2. In the Object Inspector, change the following properties:
    BorderStyle: bsDialog
    Caption: Car Inventory
    Name: frmInventory
    Position: poScreenCenter
  3. To save the project, on the Standard toolbar, click the Save All button
  4. Click the New Folder button
  5. Set the name to CarInventory1 and press Enter twice
  6. Set the name of the unit as Inventory and click Save
  7. Set the name of the project to CarInventory and click Save
  8. Press F9 to test the application
  9. Close the form and return to your programming environment
  10. From the resources that accompany our lessons, copy the files that hold the pictures of cars and paste them in the Debug sub-folder of this project
  11. Under the Code Editor, click Unit1.h (or Inventory.h)
  12. In the header file, create a structure named TCarInventory and declare its array variable named Car that contains 10 items. Also declare:
    #ifndef InventoryH
    #define InventoryH
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    struct TCarInventory
    	UnicodeString Make;
    	UnicodeString Model;
    	int  	      Year;
    	int  	      Doors;
    	double 	      PriceFrom;
    	double 	      PriceTo;
    	UnicodeString Picture;
    class TfrmInventory : public TForm
    __published:	// IDE-managed Components
    private:	// User declarations
    	TCarInventory Cars[7];
    	UnicodeString Cars1[3];
    	UnicodeString Cars2[6];
    	UnicodeString Cars3[4];
    	UnicodeString Cars4[6];
    	UnicodeString Cars5[6];
    	UnicodeString Cars6[5];
    	UnicodeString Cars7[2];
    	int ReviewPosition;
    public:		// User declarations
    	__fastcall TfrmInventory(TComponent* Owner);
    extern PACKAGE TfrmInventory *frmInventory;
  13. Save all

Creating a Track Bar

A track bar is based on a class named TTrackBar. The TTrackBar class derives from TWinControl:

TTrackBar Inheritance

To visually create a track bar, in the Win32 section of the Tool Palette, click the TTrackBar icon TTrackBar and click the form.


Characteristics of a Track Bar


The Orientation of a Track Bar

After placing a track bar control on a form or other container, by default, its assumes a horizontal position. The position of the trackbar is controlled by Orientation property, which is of type TTrackBarOrientation:

__property Comctrls::TTrackBarOrientation Orientation =

 The TTrackBarOrientation enumerator is defined as follows:

enum TTrackBarOrientation { trHorizontal, trVertical };

To visually change the direction of the control, on the Object Inspector, set the Orientation property to the desired value. For example, to make it vertical, change the field from trHorizontal to trVertical. To change this property at runtime, assign the desired value to the property. Here is an example:

void __fastcall TForm1::Button1Click(TObject *Sender)
	TrackBar1->Orientation = trVertical;

Practical LearningPractical Learning: Creating Track Bars

  1. Design the form as follows:
    Car Inventory
    Control Center Caption Kind Name Orientation
    TGroupBox TGroupBox   Car Description      
    TLabel TLabel   Make:      
    TEdit TSpeedButton       edtMake  
    TLabel TLabel   Model:      
    TEdit TSpeedButton       edtModel  
    TLabel TLabel   Year:      
    TEdit TSpeedButton       edtYear  
    TLabel TLabel   Doors:      
    TEdit TSpeedButton  
    TLabel TLabel   Price From:      
    TEdit TSpeedButton       edtPriceFrom  
    TLabel TLabel   Price To:      
    TEdit TSpeedButton       edtPriceTo  
    TImage TLabel True     imgPicture  
    TTrackBar TTrackBar     trbModel   trVertical
    TBitBtn TBitBtn     bkClose    
    TTrackBar TTrackBar     trbMake    
  2. Save all

The Minimum and Maximum Values

The Min property controls the minimum positional value of the control while the Max value controls the opposite. The user is allowed to slide only between these two values. These two properties can be set visually in the Object Inspector using their respective fields. By default, the minimum value is set to 0 and the maximum is 10. As integers, the lowest minimum allowed is INT_MIN which is Ė2147483647. The maximum allowed value is INT_MAX which is 2147483647.

To change the minimum or maximum values programmatically, assign the desired value to the appropriate property. Here is an example:

void __fastcall TForm1::Button1Click(TObject *Sender)
	TrackBar1->Min = -1205;
	TrackBar1->Max = -540;

Always make sure that the minimum value is lower than the maximum. This safe measure will allow you to better control the current value of the control. At design time, if you try inversing the values, the studio would reset them. For example, if the Min field is 12 and you try setting it to 48 when the Max field is 25, the Min field would be reset to its original value 12. At runtime, if you try setting wrong values as follows:

void __fastcall TForm1::Button1Click(TObject *Sender)
	TrackBar1->Min = 55;
	TrackBar1->Max = 12;

The minimum would be set to the previous minimum value the property had and the new maximum value would be kept. If you do not know for sure which value would be greater due to an intermediary action of the user, you can write a conditional statement that would control the minimum and the maximum values.

When using the track bar, the user can slide the thumb in the desired direction, thus changing the value of the control. While it is moving, you can control the incrementing of the thumb. By default, the thumb advances or regresses by 1 unit each time it is scrolled. This unit is controlled by the Frequency property.

Practical LearningPractical Learning:  Setting the Maximum

  1. On the form, click the bottom track bar and, in the Object Inspector, change the Max value to 6
  2. Save all

The Thumb

The thumbís visual display appears as a small standing pentagon with two straight borders. Its size is set using the ThumbLength property:

__property int ThumbLength = {read=GetThumbLength,write=SetThumbLength};

The smaller the value, the narrower the thumb. The visual appearance of the thumb is controlled by the SliderVisible property whose Boolean value is by default set to true. Therefore, if you wish to hide the thumb, set its SliderVisible property to false.

Practical LearningPractical Learning:  Setting the Thumbs

  1. On the form, click the right track box and, in the Object Inspector, change the ThumbLength value to 22
  2. On the form, click the bottom track box and, in the Object Inspector, change the ThumbLength value to 24

The Tick Marks

A track bar is also equipped with small bars "|" that serve as indicators of the position occupied by the slider. These bars are called ticks. By default, the tick marks are positioned on the same side the slider is pointing. This conditional position of the ticks is controlled by the value of TickMarks property set from the TTickMark enumerator:

enum TTickMark { tmBottomRight, tmTopLeft, tmBoth };

By default, when you add a new track bar to a form, it is horizontally oriented, the slider points down, the tick marks are positioned under the sliding field. In this setting, the TickMarks property is set to tmBottomRight. To place the tick marks above the sliding field, change the value of the TickMarks property to tmTopLeft; this also has the effect of reversing the direction of the slider. As a third option, you can have the tick marks on both sides of the slider. To get this, set the TickMarks property to tmBoth. With this value, the thumb becomes a small rectangle (changing from its pentagon shape).

The sliding field of a track bar is a rectangle with a background. It stays white even as the user slides the thumb to change the controlís value.

Practical LearningPractical Learning:  Implementing a Track Bar

  1. On the form, click the bottom track box and, in the Object Inspector, change the TickMarks to tmBoth
  2. On the form, click the bottom track box and, in the Object Inspector, change the TickMarks to tmTopLeft
    Car Inventory
  3. Save all

Track Bar Events

A track bar is important when you can get its value and use it in a transaction. The most fundamental operation you can do is to display its value in an edit or a label controls. When the value of the track bar changes, we will use its OnChange() event to track its position and display its value on a label.

Practical LearningPractical Learning:  Using Track Bar Events

  1. Double-click an unoccupied area of the form to generate its OnCreate event
  2. Return to the form and double-click the bottom track bar
  3. Return to the form and double-click the right track bar
  4. Implement the events as follows:
    #include <vcl.h>
    #pragma hdrstop
    #include "Inventory.h"
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TfrmInventory *frmInventory;
    __fastcall TfrmInventory::TfrmInventory(TComponent* Owner)
    	: TForm(Owner)
    void __fastcall TfrmInventory::FormCreate(TObject *Sender)
    	// Use the global array of cars to create a list of cars
    	Cars[0].Make  = L"Ford";
    	Cars[0].Model = L"Focus S Sedan";
    	Cars[0].Year  = 2010;
    	Cars[0].Doors = 4;
    	Cars[0].PriceFrom = 15387;
    	Cars[0].PriceTo = 16290;
    	Cars[0].Picture = L"FordFocus1.bmp";
    	// Create a list of car pictures associated with this car
    	Cars1[0] = L"FordFocus1.bmp";
    	Cars1[1] = L"FordFocus2.bmp";
    	Cars1[2] = L"FordFocus3.bmp";
    	// Do the same for this car
    	Cars[1].Make  = L"BMW";
    	Cars[1].Model = L"328i";
    	Cars[1].Year  = 2011;
    	Cars[1].Doors = 4;
    	Cars[1].PriceFrom = 30500;
    	Cars[1].PriceTo = 43,950;
    	Cars[1].Picture = L"BMW328a.bmp";
    	Cars2[0] = L"BMW328a.bmp";
    	Cars2[1] = L"BMW328b.bmp";
    	Cars2[2] = L"BMW328c.bmp";
    	Cars2[3] = L"BMW328d.bmp";
    	Cars2[4] = L"BMW328e.bmp";
    	Cars2[5] = L"BMW328f.bmp";
    	Cars[2].Make  = L"Mazda";
    	Cars[2].Model = L"Miata";
    	Cars[2].Year  = 2011;
    	Cars[2].Doors = 2;
    	Cars[2].PriceFrom = 22960;
    	Cars[2].PriceTo = 28400;
    	Cars[2].Picture = L"MazdaMiata1.bmp";
    	Cars3[0] = L"MazdaMiata1.bmp";
    	Cars3[1] = L"MazdaMiata2.bmp";
    	Cars3[2] = L"MazdaMiata3.bmp";
    	Cars3[3] = L"MazdaMiata4.bmp";
    	Cars[3].Make  = L"GMC";
    	Cars[3].Model = L"Acadia";
    	Cars[3].Year  = 2010;
    	Cars[3].Doors = 4;
    	Cars[3].PriceFrom = 31740;
    	Cars[3].PriceTo = 42185;
    	Cars[3].Picture = L"GMCAcadia1.bmp";
    	Cars4[0] = L"GMCAcadia1.bmp";
    	Cars4[1] = L"GMCAcadia2.bmp";
    	Cars4[2] = L"GMCAcadia3.bmp";
    	Cars4[3] = L"GMCAcadia4.bmp";
    	Cars4[4] = L"GMCAcadia5.bmp";
    	Cars4[5] = L"GMCAcadia6.bmp";
    	Cars[4].Make  = L"Acura";
    	Cars[4].Model = L"MDX";
    	Cars[4].Year  = 2010;
    	Cars[4].Doors = 4;
    	Cars[4].PriceFrom = 42230;
    	Cars[4].PriceTo = 53755;
    	Cars[4].Picture = L"AcuraMDX1.bmp";
    	Cars5[0] = L"AcuraMDX1.bmp";
    	Cars5[1] = L"AcuraMDX2.bmp";
    	Cars5[2] = L"AcuraMDX3.bmp";
    	Cars5[3] = L"AcuraMDX4.bmp";
    	Cars5[4] = L"AcuraMDX5.bmp";
    	Cars5[5] = L"AcuraMDX6.bmp";
    	Cars[5].Make  = L"Mercedes-Benz";
    	Cars[5].Model = L"E350";
    	Cars[5].Year  = 2010;
    	Cars[5].Doors = 4;
    	Cars[5].PriceFrom = 48050;
    	Cars[5].PriceTo = 85750;
    	Cars[5].Picture = L"MercedesBenzE350a.bmp";
    	Cars6[0] = L"MercedesBenzE350a.bmp";
    	Cars6[1] = L"MercedesBenzE350b.bmp";
    	Cars6[2] = L"MercedesBenzE350c.bmp";
    	Cars6[3] = L"MercedesBenzE350d.bmp";
    	Cars6[4] = L"MercedesBenzE350e.bmp";
    	Cars[6].Make  = L"Ford";
    	Cars[6].Model = L"E150";
    	Cars[6].Year  = 2010;
    	Cars[6].Doors = 4;
    	Cars[6].PriceFrom = 27970;
    	Cars[6].PriceTo = 34845;
    	Cars[6].Picture = L"FordE150XLTa.bmp";
    	Cars7[0] = L"FordE150XLTa.bmp";
    	Cars7[1] = L"FordE150XLTb.bmp";
    	// Behave as if the position of the bottom track bar was changed
    void __fastcall TfrmInventory::trbMakeChange(TObject *Sender)
    	// Get a reference to the position of the bottom track bar
    	ReviewPosition = trbMake->Position;
    	// Based on the current position of the track bar, display
    	// information about the car (corresponding to the current position
    	edtMake->Text = Cars[ReviewPosition].Make;
    	edtModel->Text = Cars[ReviewPosition].Model;
    	edtYear->Text = IntToStr(Cars[ReviewPosition].Year);
    	edtDoors->Text = IntToStr(Cars[ReviewPosition].Doors);
    	edtPriceFrom->Text = FloatToStr(Cars[ReviewPosition].PriceFrom);
    	edtPriceTo->Text = FloatToStr(Cars[ReviewPosition].PriceTo);
    	// Depending on the car, we don't have the same number of pictures
    	// for each car. Therefore, based on the car, change the maximum
    	// value of the right track bar
    		case 0:
    			trbModel->Max = 2;
    		case 1:
    			trbModel->Max = 5;
    		case 2:
    			trbModel->Max = 3;
    		case 3:
    			trbModel->Max = 5;
    		case 4:
    			trbModel->Max = 5;
    		case 5:
    			trbModel->Max = 4;
    		case 6:
    			trbModel->Max = 1;
    	// Since the user just got to a different car, set the position of
    	// the right track bar to the beginning
    	trbModel->Position = 0;
    void __fastcall TfrmInventory::trbModelChange(TObject *Sender)
    	// If the user changes the position of the right track bar, show a
    	// different picture
    		case 0:
    		case 1:
    		case 2:
    		case 3:
    		case 4:
    		case 5:
    		case 6:
  5. Save all
  6. Press F9 to test the application
    Car Inventory
    Car Inventory
    Car Inventory
  7. Close the form and return to your programming environment

Home Copyright © 2010-2016, FunctionX