C++ Builder Tutorials

Components in C++ Builder

A component is a "persistent" object that can appear on the IDE palette and that can be manipulated in a Form Designer.

Persistent means that components have streaming capabilities, they can read and write their properties to and from a form file (.dfm file)

Components that can be visible at run time are sometimes called visual components. Other components, which are never visible at run time, are sometimes called non-visual components (such as TTimer).


Owner and Parent

A component can "own" other components. If the Form1 owns Panel1, then Form1 is responsible for destroying Panel1 when Form1 is destroyed.

The Owner of a component is responsible for two things:
- The owned component is "freed" when its owner is freed. This means that when a form is destroyed, all the components on the form are also destroyed.
- The Owner is responsible for loading and saving the published properties of its owned controls.

The owner of a component is determined by the parameter passed to the constructor when the component is created. For components created in the form designer, the form is automatically assigned as the Owner.

The property Components of a component contains a list of all components owned by the component.
You can use Components to access any component owned by this component, such as the components owned by a form. The Components property refers to its owned components by number rather than name. It is also used internally for processing of all owned components.

Example:
String S;
S = Form1->Components[0]->Name;

The Parent of a control is the control that contains it. To obtain the parent of a component, you use the function GetParentComponent().
Example: Label1->GetParentComponent() returns the parent of Label1, thus for displaying the name of the parent of Label1, we would use the following code:

ShowMessage ( Label1->GetParentComponent()->Name ) ;



Let's have a look at useful details and code snippets for some common components, such as TForm, Tbutton, TLabel, TEdit, TMemo,... We will regularly update this list.

Note: In the examples below, S is a String variable that has been declared as:  String S;

TForm

A TForm component shows a window that is the interface to an application. It can contain text elements, buttons, input boxes, list boxes, and more.

By default, a form "owns" all the components that are on it. In turn, the form is owned by the application. Thus, when the application shuts down and its memory is freed, the memory for all forms (and all their owned components) is also freed.

When a form is loaded into memory, it loads all of the components that are on it.

When you create a new project, a form appears in the Form Designer on which you can begin your UI design. This is the main form of your application. You can customize this form by using the Object Inspector: change its name, its caption (the text in the title bar), change its appearance (size, color, border icons, border style,...) and attach event handlers (such as for OnShow).

You can add additional forms to your program with menu choice File / New / VCL Form.
You show such an extra form, say Form2, either by using Form2->Show() or Form2->ShowModal().
The difference is:
- after Show() the main program simply continues;
- after ShowModal() the main program is pauzed until Form2 is closed.

Adding a form to a project only adds a reference to it in the project file. But before you can write code that references the new form, you need to add a reference to it in the referencing forms' unit files. This is called form linking.
To link a form to another form:

  1. Select the form that needs to refer to another, for example your main form Form1.
  2. In the menu, choose File / Use Unit.
  3. Select the name of the form unit for the form to be referenced, for example Form2.
  4. Click OK.

TButton

Use TButton to put a standard push button on a form. The user clicks on buttons to initiate actions.

For a button that displays a bitmap, use a TBitBtn.
For a button that can remain in a pressed position, use TSpeedButton.

A button can have a Caption. that you can set in the Object Inspector, or in your code, for example:

Button1->Caption = "Calculate";

Note: you cannot change the color of a Tbutton's Caption. Instead, use a button type whose Caption color can be changed by changing its Font property, such as TSpeedButton or TBitBtn.

Note: buttons don't have a property "color".

TLabel

A TLabel simply displays the text that you've entered in its property Caption.

Use a TLabel to:

  • show a label next to another component; you set its caption at design time in the Object Inspector, such as a label with "Amount:" above an edit box;
  • or to display a value or message at runtime; in that case, set its caption in your code, such as:
    Label1->Caption = FloatToString(Amount);

TEdit

TEdit is a single-line edit control.

Use it to retrieve text that the user typed. Example:
S = Edit1->Text;

Edit controls can also display text to the user. An example:
S = "This is a trivial text";
Edit1->Text = S;

TMemo

TMemo is a multi-line edit control, that allows the user to enter more than one line of text.

To limit the number of characters, use the MaxLength property. The default value for MaxLength is 0, meaning that there is no character limit other than that imposed by the operating system.

TMemo is also useful for displaying lengthy information. To prevent editing by the user, set the ReadOnly property to True.

The text lines of a TMemo are contained in its property Lines. You can preset Lines with the Object Inspector, or you can load it from a text file (see the TOpenDialog example below).

To retrieve one line of the text through your code, use:
S = Memo1->Lines[i];
where i must be an integer in the range from 0 for the first line, to a maximum of
Memo1->Lines->Count - 1 for the last line.

The entire text of the TMemo as one long string can be accessed with its property Text:
S = Memo1->Text;

Several properties affect the appearence of the memo and how text is entered:

  • You can supply a horizontal, a vertical scroll bars, or both scroll bars in the memo with the ScrollBars property.
  • To prevent word wrap, set the WordWrap property to False.
  • Alignment determines how the text is aligned. Possible choices: taLeftJustify (the default), taCenter, and taRightJustify.
  • Use the Font property to change the font of the text.

At runtime, the user can cut, copy, and paste text to and from a database memo control. You can accomplish the same in your code by using the methods CutToClipboard, CopyToClipboard, and PasteFromClipboard.

TOpenDialog and TSaveDialog

Both the TOpenDialog and TSaveDialog components display a dialog box for selecting files.
The dialog appears at run time when it is activated by the Execute method.

Once the dialog is open, the user can navigate to a folder, select a filename, and click the Open button. The dialog closes and the selected filename is stored in the FileName property.

Let's suppose that you want to select a text file (a *.txt file) and load it into a TMemo component.
Use the following code:

OpenDialog1->Filter = "Text Files (*.txt)|*.txt";
if (OpenDialog1->Execute())
  Memo1->Lines->LoadFromFile(OpenDialog1->FileName);
else // the Open button was not clicked 
  ShowMessage("No file was selected");

TColorDialog

TColorDialog displays a color-selection dialog box.
The dialog appears at run time when it is activated by the Execute method.

When the user selects a color and clicks OK, the dialog closes and the selected color is stored in the Color property.

For the following example, drop a TEdit, a TButton and a TColorDialog on a form. Use the following code for the button's OnClick event:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if (ColorDialog1->Execute())
    Edit1->Color = ColorDialog1->Color;
}

If you want a message if the dialog was closed without clicking OK:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if (ColorDialog1->Execute())
    Edit1->Color = ColorDialog1->Color;
  else
    ShowMessage("Nohing selected. The color is not changed.");
}

TRichEdit

A TRichEdit lets the user enter text that includes variations in font attributes and paragraph formatting.

It provides the properties and methods to enter and work with "rich text". However, TRichEdit does not provide a user interface to make these formatting options available; your application must provide the interface components for using the rich text capabilities. To make this easier, a number of pre-defined standard actions operate on a rich edit components to perform common tasks.

  • ClearSelection deletes the selected text from the control. If no text is selected, ClearSelection does nothing.
  • Undo cancels all changes made to the text since the last call to the ClearUndo. If ClearUndo was never called, Undo rolls back all changes. To determine whether there are any changes in the undo buffer, check the CanUndo property.
  • SelAttributes describes the rich text characteristics of the selected text. If no text is selected, SelAttributes represents the attributes of the cursor position.
    Note: SelAttributes is available only at runtime.
    SelAttributes specifies characteristics such as font face, color, size, style, and pitch.
    To change a single attribute of the currently selected text, read SelAttributes, and set one of its properties.
    When inserting new text, the font characteristics of the new text will match SelAttributes.
    Example:
    RichEdit1->SelAttributes->Color = clRed;
    RichEdit1->SelAttributes->Style =
      RichEdit1->SelAttributes->Style << fsBold << fsItalic;
    RichEdit1->Lines->Add("Red, bold and italic.");
    RichEdit1->SelAttributes->Color = clBlue;
    RichEdit1->Lines->Add("This paragraph is in blue.");
    Note:  << fsBold << fsItalic adds these 2 attributes to the style.
  • Read SelText to determine the value of the selected text. Set SelText to replace the selected text with a new string. If there is no selection, but the TRichEdit has focus, set SelText to insert a new string into the text at the position of the cursor.
  • FindText(SearchStr, StartPos, Length, Options) searches for the string specified by SearchStr. Only the text in the range starting at StartPos and continuing through the next Length positions will be searched. Use Options to specify whether the search should match whole words only and whether the search should be case sensitive.
    An example, that searches the entire TRichEdit for the text "C++", without any search options:
    String SearchFor = "C++";
    int FoundAt;
    TSearchTypes SearchType = TSearchTypes(); // SearchType without any options
    FoundAt = RichEdit1->FindText(SearchFor, 0, RichEdit1->Text.Length(), SearchType);
    if (FoundAt != -1) {
      RichEdit1->SetFocus();
      RichEdit1->SelStart = FoundAt;
      RichEdit1->SelLength = SearchFor.Length();
    }
  • SaveToFile and LoadFromFile save or load your RTF text, such as:
    RichEdit1->Lines->SaveToFile(filename);
    or
    RichEdit1->Lines->LoadFromFile(filename);

    For the filename, you can use a file dialog with this filter:
    Dialog1->Filter = "RTF Files (*.rtf)|*.rtf";

TTimer

The TTimer component "fires" an OnTimer event after a preset interval (only if it is Enabled).

TTimer has an Interval property that determines how often the timer's OnTimer event occurs. The interval is given in milliseconds.

An example:
A blinking panel with "Alert".

  1. Drop a TTimer component on a form and set property Enabled to False.
  2. Drop a button on the form.
  3. Drop a panel on the form.
    Set its Caption to "Alert".
    Set its property Visible to False.
  4. Write a handler for the OnClick event of the button:
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      Panel1->Visible = true;
      Timer1->Enabled = true;
    }
  5. Write an event handler for the OnTimer of the timer:
    void __fastcall TForm1::Timer2Timer(TObject *Sender)
    {
      if (Panel1->Color != clRed)
        Panel1->Color = clRed;
      else
        Panel1->Color = clWhite;
    }

Another example:
You want the user to click on a "Yes" or "No" button. If the user doesn't take action within 5 seconds, you want to remind him to click one of the two buttons.

Timer example
    1. Drop a TTimer component on a form, set its Interval to 5000 and set Enabled to False.
    2. Add a button to the form, and name it as btnQuestion. Set its caption to "Continue?".
    3. Below that, drop a label and set its caption to "Please click Yes or No".
      Set its property Visible to False.
    4. Drop 2 buttons on the form and name them as btnYes and btnNo.
      Set their captions to "Continue?", "Yes" and "No".
    5. Set the property Visible of btnYes and of btnNo to False.
    6. Write a handler for the OnClick event of btnQuestion:
      void __fastcall TForm1::btnQuestionClick(TObject *Sender)
      {
        btnYes->Show();
        btnNo->Show();
        Timer1->Enabled = True;
      }
    7. Write an event handler for the OnTimer event of the timer:
      void __fastcall TForm1::Timer1Timer(TObject *Sender)
      {
        Timer1->Enabled = false;
        Label1->Show();
      }
    8. Write an event handler for the Onclick of btnNo:
      void __fastcall TForm1::btnYesClick(TObject *Sender)
      {
        btnQuestion->Hide();
        btnYes->Hide();
        btnNo->Hide();
        Label1->Caption = "Continued";
      }
    9. Write an event handler for the OnClick of btbYes:
      void __fastcall TForm1::btnNoClick(TObject *Sender)
      {
        btnQuestion->Hide();
        btnYes->Hide();
        btnNo->Hide();
        Label1->Caption = "Halted";
      }

See also:

  OOP in C++