Home

Windows Controls: Scroll Bars

   

Introduction to Windows Scrolling

 

Description

A scroll bar (or scrollbar, both names are recognized in Microsoft Windows) is a control that allows the user to navigate a document in two directions by clicking a button that displays an arrow. The control is equipped with one button at each of its ends. Between the buttons, there is a (long) bar and on the bar, there is a sliding object called a thumb:

Scroll Bars

To use a scroll bar on a regular monitor, the user can click one of the arrows:

Scroll Bars

In most applications, the size of the arrow buttons is fixed and is controlled by the operating system.

To use a scroll bar on a touch screen, the user can press one of the arrows. In either case, this causes the thumb to move towards the button that was clicked or pressed. The user can also click (or press) and hold the mouse (or finger) on a button. This causes the thumb to move continuously, as long as the button is held down, towards the button, until the thumb cannot move any farther. The user can also drag the thumb in one direction to move it or click (or press) between a button and the thumb. This causes the thumb to move faster than clicking a button. The thumb of a scroll bar can be positioned only along the scroll bar, between the scroll barís button. If there is an empty area between the thumb and an arrow, the user can click (or press) that empty area. This causes the thumb or document to scroll by one page.

Based on their orientation, there are two types of scroll bars: horizontal and vertical:

Scroll Bars

The horizontal scroll bar allows the user to navigate a document left and right. The vertical scroll bar allows navigating up and down. In regular applications, the size of the thmb on a scroll bar is determined by the operating system; it calculates and sets it based on the size of the document that needs to be scrolled and the area allocated to the document by the application or object that is hosting the document.

Based on their relationship with the parent control or owner, there are two types of scroll bars: those that are (automatically) associated with their parent or owner and scroll bar controls that are manually added by the programmer.

Practical LearningPractical Learning: Introducing Scroll Bars

  1. Start Embarcadero RAD Studio
  2. To start a new application, on the main menu, click File -> New -> VCL Forms Application - C++Builder
  3. In the Object Inspector, change the following properties:
    Caption: Picture Viewer
    FormStyle: fsMDIForm
    Name: frmPictureViewer
    Position: poScreenCenter
  4. In the Tool Palette, click Dialogs
  5. Click the OpenFileDialog button OpenFileDialog and click the form
  6. In the Object Inspector, change its characteristics as follows:
    Name: dlgOpen
    Title: Open a Picture
  7. In the Tool Palette, click Standard
  8. Click the TMainMenu button OpenFileDialog and click the form
  9. On the form, right-click MainMenu1 and click Menu Designer...
  10. Right-click somewhere in the Menu Designer and click Insert From Template...
  11. In the Insert Template dialog box, click MDI Frame Menu
     
    Insert Template
  12. Click OK
  13. In the Menu Designer, click the box under Exit
  14. In the Objects Inspector, change the following properties:
    Caption: &Close
    Enabled: (Uncheck to get) False
    Name: mnuFileClose
  15. Click the box under the Close menu item
  16. In the Object Inspector, click Caption, type - and press Enter
  17. Move the Close menu item, and the separator to position them under Save As...
     
    Menu Designer
  18. Double-click the Close menu item
  19. Change the document as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmPictureViewer::mnuFileCloseClick(TObject *Sender)
    {
    	// If there is at least one child document, close it
    	if( MDIChildCount > 0 )
    		ActiveMDIChild->Close();
    
    	// After closing the last document,
    	// check the number of current chil forms.
    	// If there is none, disable the Close menu item
    	if( MDIChildCount == 0 )
    		mnuFileClose->Enabled = False;
    }
    //---------------------------------------------------------------------------
  20. In the Menu Designer, click File and double-click Exit
  21. Close the Menu Designer
  22. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmPictureViewer::Exit1Click(TObject *Sender)
    {
    	Close();
    }
    //---------------------------------------------------------------------------

Automatically Generated Scroll Bars

To effectively implement their functionality, some controls must be equipped with one or two scroll bars. As we will see in various lessons that describe list-based controls such as list boxes, combo boxes, tree views, list views, etc, when the items of their list exceed the allocated client area of the control, the list should display a scroll bar to give access to the hidden part of their list. This type of automatically added scroll bar is usually positioned on the right side of the control for most Latin-based languages including US English. Consider the following Options dialog box from Embarcadero RAD Studio. In this dialog box, various sections are configured to automatically generate one or more scroll bars when they judge it necessary, which is when some items get hidden for lack of space:

Options

These types of scroll bars are automatically added by the operating system to the control that needs it, unless the programmer explicitly prevented their showing.

Introduction to Scrolling Windows Controls

Some controls are ready to display a scroll bar upon request. Such controls include the form, the memo, the RichEdit, the ScrollBox, etc. When designing one of these controls, you can ask to display or hide either or both scroll bars as you see fit. This type of scroll bar is implemented through the TScrollingWinControl class, which is derived from TWinControl:

TScrollingWinControl Inheritance

Characteristics of Windows Scrolling

  

Auto-Scrolling

Imagine you ask a control container to display a document or file, like a picture. If the item's size exceeds the client area of the container, part of the document would be hidden and the user may not be able to see that hidden part. Fortunately, to help you solve this problem the TScrollingWinControl class, the parent of TCustomForm (the parent of the TForm class), is equipped with a Boolean property named AutoScroll:

__property bool AutoScroll = {read=FAutoScroll,write=SetAutoScroll};

If the value of this property is set to its default False value, the conatiner would not display any scrollbars. If this property is set to True, when the container is asked to display a document, the compiler would compare the size of the document to the size of the body (the client area) of the container. If the document is (only) larger (or taller) than the width (or height) of the container, the container would be equipped with a horizontal (or vertical) scroll bar. If the whole size of the document is higher than the size of the client area of the container, in both the width and the height, the container would be equipped with both scroll bars. It is important to know that this property auto-generates. This means that if the current document needs one or both scroll bars, it would get them. If the document changes and the new document becomes equal to or smaller than the form, the scoll bar(s) may disappear.

Practical LearningPractical Learning: Creating an Empty Bitmap

  1. To add a new form, on the main menu, click File -> New -> Form - C++Builder
  2. In the Object Inspector, change the the following properties:
    AutoScroll: True
    Name to frmViewer
  3. In the Tool Palette, click System, click TPaintBox Paint Box and click the form
  4. In the Object Inspector, change its properties as follows:
    Left: 0
    Name: pbxPicture
    Top: 0
  5. On top of the Code Editor, click Unit1.cpp to display the first form
  6. On the main menu, click File -> Use Unit...
  7. In the Use Unit dialog box, click Unit2.cpp
  8. Click Header and click OK
  9. In the top section of the Code Editor, click Unit2.cpp
  10. Under the Code Editor, click Unit2.h
  11. In the public section, declare a few variables as follows:
    //---------------------------------------------------------------------------
    
    #ifndef ViewerH
    #define ViewerH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    
    #include <jpeg.hpp>
    #include <GIFImg.hpp>
    #include <pngimage.hpp>
    //---------------------------------------------------------------------------
    enum PictureType { Bitmap, JPEG, GIF, PNG };
    //---------------------------------------------------------------------------
    class TfrmView : public TForm
    {
    __published:	// IDE-managed Components
    private:	// User declarations
    public:		// User declarations
    	Graphics::TBitmap * bmpPicture;
    	TJPEGImage        * jpgPicture;
    	TGIFImage         * gifPicture;
    	TPngImage         * pngPicture;
    
    	PictureType pctType;
    	
    	__fastcall TfrmView(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TfrmView *frmView;
    //---------------------------------------------------------------------------
    #endif
    
  12. In the Object Inspector, click Events
  13. Double-click OnClose
  14. Implement the event as follows:
    //---------------------------------------------------------------------------
    __fastcall TfrmView::TfrmView(TComponent* Owner)
    	: TForm(Owner)
    {
    	// Initialize the variables
    	bmpPicture = new Graphics::TBitmap;
    	jpgPicture = new TJPEGImage;
    	gifPicture = new TGIFImage;
    	pngPicture = new TPngImage;
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmView::FormClose(TObject *Sender, TCloseAction &Action)
    {
    	bmpPicture->Free();
    	jpgPicture->Free();
    	gifPicture->Free();
    	pngPicture->Free();
    
    	Action = caFree;
    }
    //---------------------------------------------------------------------------
  15. In the Events section of the Object Inspector, double-click OnPaint
  16. Change the file as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmView::FormPaint(TObject *Sender)
    {
        // Display the picture from the top-left section to the end
        switch(pctType)
        {
    	case PictureType::Bitmap:
    	    pbxPicture->Canvas->Draw(0, 0, bmpPicture);
    	    break;
    	case PictureType::JPEG:
    	    pbxPicture->Canvas->Draw(0, 0, jpgPicture);
    	    break;
    	case PictureType::GIF:
    	    pbxPicture->Canvas->Draw(0, 0, gifPicture);
    	    break;
    	case PictureType::PNG:
    	    pbxPicture->Canvas->Draw(0, 0, pngPicture);
    	    break;
        }
    }
    //---------------------------------------------------------------------------
  17. In the top section of the Code Editor, click Unit1.cpp
  18. On the form, double-click MainMenu1
  19. In the Menu Designer, under File, double-click Open
  20. Close the Menu Designer
  21. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmPictureViewer::Open1Click(TObject *Sender)
    {
        if( dlgOpen->Execute() )
        {
    	TfrmViewer *frmChild = new TfrmViewer(Application);
    
    	frmChild->FormStyle = fsMDIChild;
    	mnuFileClose->Enabled = True;
    	UnicodeString fileExtension = ExtractFileExt(dlgOpen->FileName);
    
    	if( fileExtension == ".bmp" )
    	{
    		frmChild->pctType = PictureType::Bitmap;
    		// Get the picture from the file
    		frmChild->bmpPicture->LoadFromFile(dlgOpen->FileName);
    
    		// Resize the paint box to the size of the picture
    		frmChild->pbxPicture->ClientWidth  = frmChild->bmpPicture->Width;
    		frmChild->pbxPicture->ClientHeight = frmChild->bmpPicture->Height;
    	} // Do the same for the other file types
    	else if( fileExtension == ".jpg" )
    	{
    		frmChild->pctType = PictureType::JPEG;
    		frmChild->jpgPicture->LoadFromFile(dlgOpen->FileName);
    		frmChild->pbxPicture->ClientWidth  = frmChild->jpgPicture->Width;
    		frmChild->pbxPicture->ClientHeight = frmChild->jpgPicture->Height;
    	}
    	else if( fileExtension == ".gif" )
    	{
    		frmChild->pctType = PictureType::GIF;
    		frmChild->gifPicture->LoadFromFile(dlgOpen->FileName);
    
    		frmChild->pbxPicture->ClientWidth = frmChild->gifPicture->Width;
    		frmChild->pbxPicture->ClientHeight = frmChild->gifPicture->Height;
    	}
    	else if( fileExtension == ".png" )
    	{
    		frmChild->pctType = PictureType::PNG;
    		frmChild->pngPicture->LoadFromFile(dlgOpen->FileName);
    
    		frmChild->pbxPicture->ClientWidth  = frmChild->pngPicture->Width;
    		frmChild->pbxPicture->ClientHeight = frmChild->pngPicture->Height;
    	}
    	else
    	{
    		ShowMessage(L"Unknown file type");
    		return;
    	}
    
    	// Display the file name in the title bar of the child form
    	frmChild->Caption = L"File Name: " + ExtractFileName(dlgOpen->FileName);
        }
    }
    //---------------------------------------------------------------------------
  22. Press F9 to execute
  23. Open a few pictures (some are provides in the resources that accompany these lessons)
     
    Picture Viewer
  24. Close the form(s) and return to your programming environment

Scrolling In View

To show the hidden part(s) of a scrolling container, the user can scroll to that part. If the container is hosting many controls, some of them would be hidden. At any time, if there is a particular control that is hidden but that you want to reveal to the user, you can call the ScrollInView() method:

void __fastcall ScrollInView(Controls::TControl * AControl);

This method takes one argument as the name of the control you want to show. Here is an example of calling it:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	ScrollingContainer->ScrollInView(Text1);
}
//---------------------------------------------------------------------------
 
 
 

Introduction to the Scroll Bar Control

 

Description

Microsoft Windows provides a type of scroll bar, considered a complete control in its own right:

Scroll Bars

Like all other controls, this one must be explicitly created and is not added automatically but it provides most of the same basic functionality as if the operating systemís automatically added scroll bars.

Practical LearningPractical Learning: Introducing Scroll 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 for the form:
    Caption: HTML Body Tag
    Name: frmMain
  3. To save it, on the Standard toolbar, click the Save All button Save All
  4. Click the New Folder button
  5. Set the name of the new folder as BodyTag1 and press Enter twice
  6. Set the name of the unit as Formatter and click Save
  7. Set the name of the project as HTMLBodyTag and click Save
  8. In the Tool Palette, click Standard
  9. Click the TRadioGroup icon TRadioGroup and click the form
  10. In the Object Inspector, double-click (TStrings) from the Items field
  11. Type Background and press Enter. Complete the list with Text, Link, Active Link, and Visited Link
     
    String List Editor
  12. Click OK
  13. While the RadioGroup control is still selected, on the Object Inspector, change its properties as follows:
    Caption = Body Attributes
    ItemIndex = 0
    Name = grpBodyAttributes

Creating a Scroll Bar

To create a scroll bar control, in the Standard section of the Tool Palette, you can click the TScrollBar button and click a container. The scroll bar is one of the earliest controls of the Microsoft Windows operating system. To create it using the Win32 approach call the CreateWindow() or the CreateWindowEx() functions and specify the class name as SCROLLBAR. If you decide to create it in Win32, you would need to configure all of its functionality. In the VCL, all operations that are needed on a scroll bar control are ready to be used.

In the VCL, a scroll bar control is implemented by a class named TScrollBar. The TScrollBar class is derived from the TWinControl class:

TScrollBar Inheritance

Notice that the TScrollBar class is not derived from the TScrollingWinControl. This is because the scroll bar is not a control but the controls that use automatic scroll bars need a mechanism to get scroll bars when they need them.

To programmatically create a scrollbar, declare a variable of type TScrollBar. Specify the owner of the control, which is usually the form on which it is positioned. Also specify the parent of the control. This is usually the form but can also be any container that is hosting the scroll bar. This dynamic creation can be inside of an event or a function. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TScrollBar * Scroller = new TScrollBar(Form1);
	Scroller->Parent = Form1;
}
//---------------------------------------------------------------------------

After declaring the variable, you can set its properties as desired.

Practical LearningPractical Learning: Creating a Scroll Bar

  1. In the Standard section of the Tool Palette, click the TScrollBar control TScrollBar and, on the form, click on the right side of the panel
  2. On the Object Inspector, click Name and type scrRed

Characteristics of the Scroll Bar Control

 

The Kind of Scroll Bar

By default, when you add a scroll bar to a form (or other container), the control assumes the horizontal position. This position is controlled by the Kind property whose default value is sbHorizontal. To change the direction of the control to vertical, set this property to sbVertical. The Kind property is controlled by the TScrollBarKind enumerator defined as follows:

enum TScrollBarKind { sbHorizontal, sbVertical };

To set this property programmatically, assign the desired value. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	ScrollBar1->Kind = sbVertical;
}
//---------------------------------------------------------------------------

Practical LearningPPractical Learning: Setting the Scroll Bar Kind

  • Make sure the scroll bar is still selected on the form.
    On the Object Inspector, click Kind and select sbVertical

The Minimum and Maximum Positions

When using a scroll bar, the user can navigate from one end of the control to the other end. These are the controlís minimum and maximum values. For a horizontal scrollbar, the minimum is the far left position that the bar can assume. For a vertical scrollbar, the minimum is the most top position. The maxima are the opposites. These two values are controlled by the Min and Max properties.

By default, a newly added scroll bar allows scrolling from 0 to 100. To change these values at design time, type an integer number for each field in the Object Inspector. The lowest number the Min property can have is Ė2147483648 and the highest number for Max would be 2147483647.

Here is an example of programming setting the maximum value:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TScrollBar * Scroller = new TScrollBar(Form1);
	Scroller->Parent = Form1;
	Scroller->Left = 24;
	Scroller->Width = 228;
	Scroller->Top = 35;
	Scroller->Kind = sbVertical;
	Scroller->Max = 1500;
}
//---------------------------------------------------------------------------

Practical LearningPractical Learning: Setting the Maximum Value

  • Make sure the scroll bar is still selected on the form.
    On the Object Inspector, click Max and type 255

The Position of a Scroll Bar

The primary technique the user applies to a scroll bar is to click (or press, on a touch screen) one of the arrows at the ends of the control. As the bar slides inside of the control, it assumes an integer position from Min to Max. At design time, you can use the Position property to set the position that the scroll bar would assume when the form opens. If you visually set the Position to a value less than the Min, the Object Inspector would restore it to the Min value. If you visually set a Position greater than the Max, the Object Inspector would assign it the Max value.

To programmatically set the position of the bar, assign the desired value, which must be between Min and Max, to the Position property. At run time, when the user scrolls the control, you can find the position of the thumb by getting the value of the Position property. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	Label1->Caption = ScrollBar1->Position;
	Label2->Caption = ScrollBar2->Position;
}
//---------------------------------------------------------------------------
Scroll Bars
 

Practical LearningPractical Learning: Setting and Using the Position

  1. Make sure the scroll bar is still selected on the form.
    On the Object Inspector, click Position, type 255, and press Enter
  2. Complete the design of the form as follows:
     
    Body Tag Formatter
     
    Control Name Text/Caption Other Properties
    Form frmMain Body Tag Formatter BorderStyle: bsDialog
    Position: poScreenCenter
    RadioGroup grpBodyAttributes Body Attributes ItemIndex: 0
    Edit edtBackground #000000  
    Edit edtText #0000FF  
    Edit edtLink #FF0000  
    Edit edtALink #008000  
    Edit edtVLink #800000  
    Label   Preview ___________  
    Panel pnlPreview   Color: clWhite
    Label   R  
    ScrollBar scrRed   Kind: sbVertical
    Max: 255
    Position: 255
    Label   G  
    ScrollBar scrGreen   Kind: sbVertical
    Max: 255
    Value: 255
    Label   B  
    ScrollBar scrBlue   Kind: sbVertical
    Max: 255
    Value: 255
    BitBtn   &Close Kind: bkClose
    Memo mmoPreview   Lines: Nothing
    Edit edtPreviewText Body tag formatter and colorizer Font->Color: clBlue
    ReadOnly: true
    Edit edtPreviewLink Sample text as link Font->Color: clRed
    ReadOnly: true
    Edit edtPreviewALink Active link that is being visited Font->Color: clGreen
    ReadOnly: true
    Edit edtPreviewVLink This link has been already been visited Font->Color: clMaroon
    ReadOnly: true
    GroupBox   Hexadecimal  
    Label   Red:  
    Edit edtHexaRed 00  
    Label   Green:  
    Edit edtHexaGreen 00  
    Label   Blue:  
    Edit edtHexaBlue 00  
    GroupBox   Numeric  
    Label   Red:  
    Edit edtRed 00  
    Label   Green:  
    Edit edtGreen 00  
    Label   Blue:  
    Edit edtBlue 00  
    BitBtn btnCopy Cop&y  
    Edit edtBody <body bgcolor="#FFFFFF" text="#0000FF" link="#FF0000" alink="#008000" vlink="#800000">
  3. Access each edit box in the lower-left memo and set its BorderStyle property to bsNone
     
  4. In the header file of the form, declare the following private variables:
    private:	// User declarations
        AnsiString HexBG, HexText, HexLink, HexALink, HexVLink;
        
    public:		// User declarations
        __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
  5. In the ClassExplorer window, right-click TForm1  and click New Method...
  6. Set the method options as follows:
    Method Name: ApplyColor
    Function Result: void
    Visibility: private
    Directives: __fastcall

     
    Add Method
  7. Click OK
  8. Implement the method as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::ApplyColor()
    {
        //TODO: Add your source code here
        // Retrieve the current hexadecimal colors from their Edit controls
        HexBG = edtBackground->Text;
        HexText = edtText->Text;
        HexLink = edtLink->Text;
        HexALink = edtALink->Text;
        HexVLink = edtVLink->Text;
    
        // Get the integral position of each ScrollBar control
        int Red   = 255 - scrRed->Position;
        int Green = 255 - scrGreen->Position;
        int Blue  = 255 - scrBlue->Position;
    
        // Display the position of each ScrollBar
        // in its corresponding Edit control
        edtRed->Text   = Red;
        edtGreen->Text = Green;
        edtBlue->Text  = Blue;
    
        // Get the hexadecimal equivalent of each ScrollBar control
        AnsiString HexRed   = IntToHex(Red, 2);
        AnsiString HexGreen = IntToHex(Green, 2);
        AnsiString HexBlue  = IntToHex(Blue, 2);
    
        // Display the hexadecimal value in the appropriate Edit controls
        edtHexaRed->Text   = HexRed;
        edtHexaGreen->Text = HexGreen;
        edtHexaBlue->Text  = HexBlue;
    
        // Change the color of the Preview panel
        // according to the values of the ScrollBar positions
        pnlPreview->Color = TColor( RGB(Red, Green, Blue) );
    
        // Get the position of each ScrollBar control
        // Create a hexadecimal color starting with #
        // And display the color in the appropriate Edit control
        switch( grpBodyAttributes->ItemIndex )
        {
        case 0:
            edtBackground->Text = "#" +
                                  IntToHex(Red, 2) +
                                  IntToHex(Green, 2) +
                                  IntToHex(Blue, 2);
            mmoPreview->Color = pnlPreview->Color;
            edtPreviewText->Color = pnlPreview->Color;
            edtPreviewLink->Color = pnlPreview->Color;
            edtPreviewALink->Color = pnlPreview->Color;
            edtPreviewVLink->Color = pnlPreview->Color;
            HexBG = edtBackground->Text;
            break;
        case 1:
            edtText->Text = "#" +
                            IntToHex(Red, 2) +
                            IntToHex(Green, 2) +
                            IntToHex(Blue, 2);
            edtPreviewText->Font->Color = TColor( RGB(Red, Green, Blue) );
            HexText = edtText->Text;
            break;
    
        case 2:
            edtLink->Text = "#" +
                            IntToHex(Red, 2) +
                            IntToHex(Green, 2) +
                            IntToHex(Blue, 2);
            edtPreviewLink->Font->Color = TColor( RGB(Red, Green, Blue) );
            HexLink = edtLink->Text;
            break;
    
        case 3:
            edtALink->Text = "#" +
                             IntToHex(Red, 2) +
                             IntToHex(Green, 2) +
                             IntToHex(Blue, 2);
            edtPreviewALink->Font->Color = TColor( RGB(Red, Green, Blue) );
            HexALink = edtALink->Text;
            break;
    
        case 4:
            edtVLink->Text = "#" +
                             IntToHex(Red, 2) +
                             IntToHex(Green, 2) +
                             IntToHex(Blue, 2);
            edtPreviewVLink->Font->Color = TColor( RGB(Red, Green, Blue) );
            HexVLink = edtVLink->Text;
            break;
        }
    
        // Update the contents of the bottom Edit control
        edtBody->Text = "<body bgcolor=\"" +
                        HexBG + L"\" text=\"" +
                        HexText + L"\" link=\"" +
                        HexLink + L"\" alink=\"" +
                        HexALink + L"\" vlink=\"" +
                        HexVLink + L"\">";
    }
    //---------------------------------------------------------------------------
  9. Save all
  10. Press F12 to return to the form

The Small Change

When the user clicks (or presses) an arrow of a scroll bar, the bar slides one unit. This unit is called SmallChange and is set to 1 by default. If you want the bar to slide more than one unit, change the SmallChange property to an integer value between Min and Max. The higher the value, the faster the sliding would occur because the bar would jump by SmallChange units. Here is an example of programming setting the small change:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TScrollBar * Scroller = new TScrollBar(Form1);
	Scroller->Parent = Form1;
	Scroller->Left = 24;
	Scroller->Width = 228;
	Scroller->Top = 35;
	Scroller->Kind = sbVertical;
	Scroller->Max = 1500;
	Scroller->Position = 780;
	Scroller->SmallChange = 5;
}
//---------------------------------------------------------------------------

The Large Change

There are two main ways the user can scroll faster using scroll bars: by pressing either page buttons or by clicking (or manually dragging) the scrolling region. The amount covered using this technique is controlled by the LargeChange property. Once again, the user can scroll only between Min and Max. This means that you can set this value only to an integer from Min to Max.

 To find the scrolling amount, the compiler would divide the actual scrolling range (the difference between the Max and Min) by the LargeChange value. When the user clicks (or touches) in the scrolling region or presses the Page Up or Page Down keys, the bar would jump by LargeChange up to the scrolling amount value. You can change the LargeChange property programmatically as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	ScrollBar1->Kind = sbVertical;
	ScrollBar1->Min = -122;
	ScrollBar1->Max = 240;
	ScrollBar1->Position = 38;
	ScrollBar1->SmallChange = 4;
	ScrollBar1->LargeChange = 20;
}
//---------------------------------------------------------------------------

The Page Size

The bar inside the scroll region has a size relative to the Min and Max values. By default, it is a square of the approximate size of the arrow buttons. This size of the bar is controlled by the PageSize property. Approximately, this represents the percentage of the scrolling range (the difference between the Max and Min). You can change this value at design time in the Object Inspector, by an integer value between Min and Max. To change it programmatically, assign the desired integer to the PageSize property. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TScrollBar * Scroller = new TScrollBar(Form1);
	Scroller->Parent = Form1;
	Scroller->Left = 24;
	Scroller->Width = 228;
	Scroller->Top = 35;
	Scroller->Kind = sbVertical;
	Scroller->Max = 1500;
	Scroller->Position = 780;
	Scroller->SmallChange = 5;
	Scroller->LargeChange = 150;
	Scroller->PageSize = 250;
	Scroller->SetParams(780, 0, 1500);
}
//---------------------------------------------------------------------------

Using a Scroll Bar

The most fundament event of a scrollbar occurs when the bar slides. This happens when:

  • The user clicks one of the arrows (or manually presses one of the arrows on a touch screen)
  • The user presses one of the arrow keys
  • The user presses Page Up or Page Down

Every time the user performs one of these actions, the position of the bar changes unless it is already at one of the extremes. When the position of the bar has changed, a message is sent to the operating system that the bar has changed its position. Using the OnChange event of the scrollbar, you can tell the compiler what to do. Fundamentally you can find out the new position and display it on a label. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
	Label1->Caption = ScrollBar1->Position;
}
//---------------------------------------------------------------------------

The OnScroll event occurs when the user scrolls the bar. This event is appropriate if or when you want to capture the specific action that caused the scrolling action. These actions relate to the TScrollCode enumerator:

enum TScrollCode { scLineUp, scLineDown, scPageUp, scPageDown, 
		   scPosition, scTrack, scTop, scBottom, scEndScroll };

The syntax of the OnScroll event is:

void __fastcall (__closure *TScrollEvent)(System::TObject* Sender,
					  TScrollCode ScrollCode,
					  int &ScrollPos);

Practical LearningPractical Learning: Using the Scroll Bar Events

  1. Double-click the left scroll bar
  2. Press F12 to return to the form
  3. Double-click the middle scroll bar
  4. Press F12 to return to the form
  5. Double-click the right scroll bar
  6. Implement their OnChange events as follows:
    //---------------------------------------------------------------------------
    void __fastcall TForm1::scrRedChange(TObject *Sender)
    {
        ApplyColor();
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::scrGreenChange(TObject *Sender)
    {
        ApplyColor();
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::scrBlueChange(TObject *Sender)
    {
        ApplyColor();
    }
    //---------------------------------------------------------------------------
  7. Test the application and return to your programming environment
  8. When the user clicks a radio button from the Body Attributes group box, we need to display its color on the Preview panel. When a particular button is clicked, we will retrieve the color of its font from the Body text box, translate that color into red, green, and blue values, and then use those values to automatically update the scroll bars and the edit boxes. While we are at it, we also need to update the corresponding text box in the Body Attributes group box. Since this functionality will be used by all radio buttons in the group, we will use a global function to which we can pass two variables.
    When the user clicks a particular radio button, that button is represented by a text box in the lower-left Body section. We need to get the color of that edit box and pass it to our function. Since the clicked radio button has a corresponding text box in the Body Attributes group box, we need to change/update that value with the hexadecimal value of the first argument. Therefore, we will pass a String argument to our function.
    In the header file of the form, declare a method as follows:
    private:	// User declarations
        AnsiString HexBG, HexText, HexLink, HexALink, HexVLink;
        void __fastcall ApplyColor();
        void __fastcall ClickOption(TColor Clr, AnsiString Result);
    public:		// User declarations
        __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
  9. In the source code of the form, implement the function as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::ClickOption(TColor Clr, AnsiString Result)
    {
        long lngColor;
        int Red, Green, Blue;
    
        pnlPreview->Color = Clr;
        lngColor = Clr;
    
        Red = 255 - (lngColor % 256);
        Green = 255 - ((lngColor / 256) % 256);
        Blue = 255 - (lngColor / 65536);
    
        scrRed->Position = Red;
        scrGreen->Position = Green;
        scrBlue->Position = Blue;
    
        edtRed->Text   = Red;
        edtGreen->Text = Green;
        edtBlue->Text  = Blue;
    
        edtHexaRed->Text = IntToHex(Red, 2);
        edtHexaGreen->Text = IntToHex(Green, 2);
        edtHexaBlue->Text = IntToHex(Blue, 2);
    
        Result = "#" + IntToHex(Red, 2) + IntToHex(Green, 2) + IntToHex(Blue, 2);
    }
    //---------------------------------------------------------------------------
  10. Double-click the grpBodyAttributes RadioGroup control and implement its OnClick as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::grpBodyAttributesClick(TObject *Sender)
    {
        // If the user clicks a button from the RadioGroup control
        // find out what button the user clicked
        // set color of the panel to that of the radio button that was clicked
        TColor BGColor = mmoPreview->Color;
    
        mmoPreview->Color      = BGColor;
        edtPreviewText->Color  = BGColor;
        edtPreviewLink->Color  = BGColor;
        edtPreviewALink->Color = BGColor;
        edtPreviewVLink->Color = BGColor;
    
        switch(grpBodyAttributes->ItemIndex)
        {
        case 0:
            ClickOption(mmoPreview->Color, edtBackground->Text);
            HexBG = edtBackground->Text;
            break;
        case 1:
            ClickOption(edtPreviewText->Font->Color, edtText->Text);
            HexText = edtText->Text;
            break;
        case 2:
            ClickOption(edtPreviewLink->Font->Color, edtLink->Text);
            HexLink = edtLink->Text;
            break;
        case 3:
            ClickOption(edtPreviewALink->Font->Color, edtALink->Text);
            HexALink = edtALink->Text;
            break;
        case 4:
            ClickOption(edtPreviewVLink->Font->Color, edtVLink->Text);
            HexVLink = edtVLink->Text;
            break;
        }
    }
    //---------------------------------------------------------------------------
  11. Save and test the application then return to your programming environment
  12. Double-click the Copy button and implement it as follows:
    //---------------------------------------------------------------------------
    void __fastcall TForm1::btnCopyClick(TObject *Sender)
    {
        edtBody->SelectAll();
        edtBody->CopyToClipboard();
    }
    //---------------------------------------------------------------------------
  13. Save all
  14. Press F9 to test the application
     
    HTML Body Tag Formatter
 
 
   
 

Home Copyright © 2010-2011 FunctionX, Inc.