Home

The Form

 

Characteristics of Forms

 

Introduction

The form is the primary object of a VCL application. It is rectangular window whose main purpose is to carry, host, or hold other controls to allow the user to interact with the computer. Although there are various types of parent containers we will use, the form is the commonly and regularly used.

When C++ Builder starts, it creates a starting form and initializes an application. You can use such as form as you see fit. If you need additional forms, you can create them visually by clicking File -> New -> Form on the main menu. You can also click the New Form button on the Standard toolbar. Alternatively, you can display the New Items dialog box from where you would select the Form icon.

Another technique you can use is to create a form programmatically. To do this, declare a pointer to the TForm class using the new operator. Like every other control, you must specify the owner of the form that will be responsible for destroying it. This owner is usually the form that is calling it.

The System Icon

The top section of a form or a dialog box is called a title bar:

On the left side of the form's title bar, there is a small picture called an icon. By default, C++ Builder uses an icon shipped with the compiler. If you want to use your own icon, you can specify it using the Icon property. To do this, on the Object Inspector, you can either double-click the (None) value of the Icon field or click the ellipsis button of the field. This would call the Picture Editor dialog box:

After selecting the icon and clicking Open, the icon would be made available in the Picture Editor dialog box:

After clicking OK, the new icon would be used as the system icon of the form:

The System Menu

The icon used on the title bar possesses a menu called the system menu. This menu displays if you click the icon:

The system menu of the icon's title bar allows you to perform the common actions of a regular Windows form. If you do not want to display the icon and its menu, refer to the section on the BorderIcons below.

The Caption

On the right side of the system icon, there is long bar that is actually usually referred to as the title bar. This section displays a word or a group of words known as the caption of the form. By default, the title bar displays the name of the form. To customize the text displayed on the title bar, on the Object Inspector, change the text of the Caption property.

At design time, you can only set the caption as text. The caption can be any type of string. At run time, you can control and programmatically display anything on the caption of the form. It can consist of an expression or the result of a calculation. To change the caption at run time, you can use a function, a method, or an event. Just type “Caption = “ and the sentence you want. For example, you can display today’s date on the caption as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::ChangingFormCaption()
{
    Caption = "Today is " + Date();
}
//---------------------------------------------------------------------------

You can also indirectly control the caption. For example, after the user has typed his or her name in an edit box, you can display it in the form’s caption as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::ChangingFormCaption()
{
	Caption = Edit1->Text;
}
//---------------------------------------------------------------------------

The System Buttons

On the right side caption, there are three system buttons that allow minimizing , maximizing , restoring or closing the form as a window. The presence, absence, or appearance of the system buttons is controlled by the BorderIcons property. To control this property, you can click its + button to expand it to display its four possible values: biSystemMenu, biMinimize, biMaximimize, and biHelp:

The BorderIcons property is a (Pascal-style) set, which means it can use one or more values in any allowed combination. Each member of the set can have a true or false value. If you set the biSystemMenu property to true, regardless of the values of the other fields of the BorderIcons property, the form would have neither the system icon (which also makes the system menu unavailable) nor the system buttons. If a form does not have a system close button, you should make sure the user has a way to close the form:

This dialog box does not present system buttons. The user would not have any inherent way to close it unless the programmer explicitly presents a button to close it, which was taken care of by the presence of the OK and Cancel buttons.

Using a combination of the biSystemMenu, the biMinimize and the biMaximimize properties, you can control the availability of the system buttons:

biSystemMenu = false

Notice that there is no system button

biSystemMenu = true

biMinimize = falsebiMaximize = trueNotice that the Minimize button is disabled

biSystemMenu = true
biMinimize = true
biMaximize = false

Notice that the Maximize button is disabled

biSystemMenu = true
biMinimize = true
biMaximize = true

Both the Minimize and Maximize buttons are enabled

biSystemMenu = true
biMinimize = false
biMaximize = false

Notice that only the system Close button is available

The biHelp property works only if the form is a dialog box. It does not bear any role on the title bar of a regular form.

You can also programmatically control the system buttons. Since the BorderIcons property is a set, you must use the overloaded extractor operators. To remove or set a property to false, use the >> operator. To include or set a property to true, use the << operator. For example, to set the biSystemMenu property to false, you can use code such as:

biSystemMenu = false

is equivalent to:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	BorderIcons = TBorderIcons() >> biSystemMenu;
}
//---------------------------------------------------------------------------

biSystemMenu = true
biMinimize = false
biMaximize = true

is equivalent to:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	BorderIcons = TBorderIcons() << biSystemMenu >> biMinimize << biMaximize;
}
//---------------------------------------------------------------------------

biSystemMenu = true
biMinimize = true
biMaximize = false

is equivalent to:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	BorderIcons = TBorderIcons() << biSystemMenu << biMinimize >> biMaximize;
}
//---------------------------------------------------------------------------

biSystemMenu = true
biMinimize = false
biMaximize = false

is equivalent to:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
	BorderIcons = TBorderIcons() << biSystemMenu >> biMinimize >> biMaximize;
}
//---------------------------------------------------------------------------

If you do not explicitly define the values of the BorderIcons, by default, the form would be equipped with all system buttons.

Form and Dialog Box Positioning

One of the ways you can use the title bar is to move the form at design time. The location of a form is set at design time because the VCL provides another property that follows the directives of the design. At design time, you can position the form anywhere on your screen and when you run the application, the form would appear following that position. This is based on the fact that the position of the form is controlled by the TPosition enumerator. The default position of the form is recognized as the way it was designed if you do not change the Position property. The default value of the Position property is poDesigned.

The Borders

One of the most visual aspects of an object's appearance is its border. A border is a line that sets the visual limits of an object. Most objects, including a form, have four borders: left, top, right, and bottom. In VCL applications, the borders of a form are controlled by a property called BorderStyle. This is also the main property that specifies whether you are creating a regular form or a dialog box.

To control the appearance of the borders of your form, on the Object Inspector, if you click BorderStyle, you would see that it is a combo box property. The BorderStyle property is an enumerator and you can choose one of its values needed for your form.

By default, a form is designed to be resizable using the bsSizeable value. In this case the user can change its width and its height by dragging one of its borders or corners.
If you set the BorderStyle property to bsDialog, the user will not be able to resize the dialog. This is the default and the mostly used characteristics for a dialog window. You should always use it if you want the window to be a dialog box.
If you set the BorderStyle property to bsDialog and have a Help file you want to use on the dialog box, you can set the biHelp of the BorderIcons property to true. This would display a What's This button on the title bar.
A BorderStyle set with bsSingle looks like one set with the bsSizeable. The difference is that the user cannot resize it.
A floating window is a form used to let the user move it around while she is working on the main form or dialog. This form is usually modeless, which means the user does not have to close it to continue working. If you want to create a floating modeless window, you should set the form’s BorderStyle to bsSizeToolWin. The window has a short title bar and it can be resized.
Like the sizable tool window, a form with bsToolWindow has a short title bar and is also a prime candidate for a floating window. Unlike the form with bsSizeToolWin, the user cannot resize a bsToolWindow form.
A Form whose BorderStyle is set to bsNone has neither a title bar nor borders.

To change a property programmatically, assign one of the above values to the BorderStyle variable. Here is an example that would transform the form in a dialog box:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	BorderStyle = bsDialog;
}
//---------------------------------------------------------------------------

The Window State of a Form 

When a form appears as it was designed, it is said to be "normal". C++ Builder allows you to have the form minimized or maximized when the application is launched. This ability is controlled by the WindowState property. The default value of this property is wsNormal, which means the form would appear in a normal fashion. If you want the form to be minimized or maximized at startup, in the Object Inspector, select the desired value for the WindowState property.

To control the window’s state programmatically, simply assign the wsMaximized or the wsMinimized value to the WindowState property. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
	WindowState = wsMaximized;
}
//---------------------------------------------------------------------------

If you want to check the state of a window before taking action, simply use a conditional statement to compare its WindowState property with the wsNormal, the wsMaximized, or the wsMinimized values. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Panel1Click(TObject *Sender)
{
	if( WindowState == wsNormal )
		WindowState = wsMaximized;
	else if( WindowState == wsMaximized )
		WindowState = wsMinimized;
	else
		WindowState = wsMaximized;
}
//---------------------------------------------------------------------------

The Body of a Form

The area that a form makes available to its control is its body. As the main container of Windows controls, a form provides some particular properties to the controls it hosts. The client area of a form is represented by the ClientRect property. This property can be used to get the dimensions of the body of the form. Like the TControl::ClientRect property, the TForm::ClientRect property provides the width and the eight of the client area, omitting the location (left and top) which is set to the client origin (0, 0) located on the top-left corner of the body of the form. Alternatively, to get the width of the client area of the form, you can call the ClientWidth property. To get the height of the client area, use the ClientHeight. The client aspects can be illustrated as follows:

Overall, you will hardly be concerned with the dimensions of the client area, unless you want to draw or render an image. If you do not have a particular reason, let C++ Builder take care of the client area.

Form’s Transparency

An object is referred to as transparent when you can see through it. If you are working under Windows 2000 or later running on a Pentium or equivalent, you can make your form transparent. To create a transparent form, set the AlphaBlend Boolean property to true from its default false value. Once this property is set to true, you can use the AlphaBlendValue property to set the degree of transparency. The value must be a BYTE integer between 0 and 255. At 0, you would not see the form at all. The only presence of the form would be on the taskbar. At 255, the form would appear as if the property were not applied.

Form Methods

 

Form Creation

The form in implemented by the TForm class which itself is derived from TCustomForm. Like every other control, the form is equipped with a constructor that allows you to dynamically create it.

Form Closure

When the user has finished using a form, he or she must be able to close it. Closing a form is made possible by a simple call to the Close() method. Its syntax is:

void __fastcall Close();

Although this method can be used to close any form of an application, if it is called by the main form, it also closes the application.

Forms Messages and Events

 

Form Creation

When an application made of a form is launched, the form must be created to display to the user. At the form gets created, it initialize its controls. This is done before the form can display to the screen. At this time the OnCreate() event fires. This is a TNotifyEvent event, which means that it does not take any argument other than the Sender, which is a TObject type.

OnCreate() is the default event of a form. This means that if you double-click the form, the code of this event would be created and made ready for you.

Practical Learning Practical Learning: Creating a Form

 
  1. Create a new project with its default form
  2. Save it in a new folder named FormEvents
  3. Save the unit as Exercise and save the project as FormEvents
  4. To use the OnCreate() event , double-click the middle of the form
  5. Implement the OnCreate event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    	ShowMessage("The form has been created");
    }
    //---------------------------------------------------------------------------
  6. Test the application. Close it and return to Borland C++ Builder

Form Showing

After the form has been created, it must display to the user. If the application contains more than one form, you can display it. To display a form, just like any control, we saw that the TControl::Show() method must be called. If the application is being launched, it would call this method to display the main form of the application. If you have more than one form and you want to display the other form, you can call the TControl::Show() method.

When the TControl::Show() method is called, the OnShow() event is fired. This allows you to perform any last minute processing before the form can display.

Practical Learning Practical Learning: Showing a Form

 
  1. On the Events tab of the Object Inspector, double-click the right field of OnShow and implement the OnShow() event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormShow(TObject *Sender)
    {
    	ShowMessage("The form is showing");
    }
    //---------------------------------------------------------------------------
  2. Test the application. Then close it and return to Borland C++ Builder

Form Activation and Deactivation

When two or more forms are running on the computer, only one can receive input from the user, that is, only one can actually be directly used at one particular time. Such a window has a title bar with the color identified in Control Panel as Active Window. The other window(s), if any, display(s) its/their title bar with a color called Inactive Window:

Display Properties

To manage this setting, the windows are organized in a 3-dimensional coordinate system and they are incrementally positioned on the Z coordinate, which defines the (0, 0, 0) origin on the screen (on the top-left corner of your monitor) with Z coordinate coming from the screen towards you.

In order to use a form other than the one that is active, it must be activated. To do this, the OnActivate() event must be fired. OnActivate() is a TNotifyEvent type of event.

If there is more than one form or application on the screen, only one can be in front of the others and be able to receive input from the others. If a form is not active and you want to bring it to the top, you must activate it, which sends the OnActivate() event. When a form is being activated, the one that was on top would become deactivated. The form that was on top, when losing focus, would fire the OnDeactivate() event.

Practical Learning Practical Learning: Activating a Form

 
  1. On the Events tab of the Object Inspector, double-click the right field of OnActivate and implement the event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormActivate(TObject *Sender)
    {
    	ShowMessage("The form is now activated");
    }
    //---------------------------------------------------------------------------
  2. Execute the application to display the form. Then close it
  3. Display the starting code for the OnDeactivate event and implement it as follows:
        
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormDeactivate(TObject *Sender)
    {
    	ShowMessage("Our form is deactivated");
    }
    //---------------------------------------------------------------------------
  4. Execute the application to display the form
  5. While the form is displaying, open Notepad to deactivate the form
  6. From the taskbar, click the button of our form to activate it
  7. After experimenting with the form, close it and return to Borland C++ Builder

Window Painting

Whether a form has just been created or it needs to be shown, the operating system must display it on the screen. To do this, the form colors and other visual aspects must be retrieved and restored. This is done by painting it (the form). If the window was hidden somewhere such as behind another window or was minimized, when it comes up, the operating system needs to paint it.

When a form gets painted, it fires the OnPaint() event. This event also is a TNotifyEvent type.

Practical Learning Practical Learning: Painting the Form

 
  1. From the Events tab of the Object Inspector, display the starting code of the OnPaint event and implement it:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormPaint(TObject *Sender)
    {
    	ShowMessage("Window Painting: A hobby or a habit?");
    }
    //---------------------------------------------------------------------------
  2. Test the application and return to Borland C++ Builder

Window Sizing

When using an application, one of the actions a user can perform on a form is to change its size, provided the form allows it. Also, some time-to-time, if possible, the user can minimize, maximize, or restore a window. Whenever any of these actions occur, the operating system must keep track of the location and size of a window. For example, if a previously minimized or maximized window is being restored, the operating system must remember where the form was previously positioned and what its dimensions were.

When the size of a form has been changed, it fires the OnResize() event, which is a TNotifyEvent type.

Practical Learning Practical Learning: Resizing a Form

 
  1. On the Events tab of the Object Inspector, double-click the right field of OnResize and implement the event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormResize(TObject *Sender)
    {
    	ShowMessage("Changing size or changing sides - Who knows?");
    }
    //---------------------------------------------------------------------------
  2. Execute the application and return to Borland C++ Builder

Form Closure

As mentioned above, the user can close the form after using it. When the form is being closed, it fires the OnClose() event. This gives you the opportunity to perform any last minute processing such as finding out some information about the application or the form itself before the form is actually closed. The OnClose() event is a TCloseEvent function pointer whose syntax is:

void __fastcall OnClose(TObject *Sender, TCloseAction &Action);

When the form is being closed, you can use the Action argument to specify how you want the closing to be performed. This argument is a value of the TCloseAction enumerator whose members are:

Value Description
caNone The form must not be closed at all
caHide The form must be hidden but not closed
caFree The form must be closed and its memory freed
caMinimize The form must be minimized and not closed
 

Practical Learning Practical Learning: Resizing a Form

 
  1. On the Events tab of the Object Inspector, double-click the right field of OnClose and implement the event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
    	ShowMessage("Time to close");
    }
    //---------------------------------------------------------------------------
  2. Execute the application and return to Borland C++ Builder

Form Destruction

Once the form has been closed, the operating system must destroy it and reclaim the memory space it was using. This causes the OnDestroy() event to fire. OnDestroy() is a TNotifyEvent. If you had dynamically created some controls using the form’s OnCreate() event, use the OnDestroy() event to destroy them.

Application of Forms

 

Multiple Forms

When you start Borland C++ Builder, it creates a starting form for you. If one form is not enough for your application, you can add as many as necessary. To add (or to create) a (new) form:

  • On the main menu, you can click File -> New -> Form
  • On the main menu, you can also click File -> New -> Other... and, in the New Items dialog box, you can double-click Form
  • On the View toolbar, you can click the New Form button 

Any of these techniques will add a new form to your application. If your application is using various forms and you want to display a particular one at design time, on the main menu, you can click View -> Forms, which would open the View Form dialog box. From there, you can select the desired form and click OK.

If you visually add two (or more) forms to your application, you may need to link them, allow one to call the other. Since each form is created in its own unit, to let one form know about the existence of another, you must include its unit. A form or unit that wants to communicate with another is called a client of the form. For example, if Unit2 wants to use information stored in, or controlled by, Unit1, Unit2 needs to include Unit1 in its list of header files; and Unit2 becomes a client of Unit.

There are two simple ways you can include a unit’s header in another file. Imagine you have created Form1 stored in Unit1 and Form2 stored in Unit2. If you want to have access to Form2 from Form1, using C++, on top of the source file of Unit1, include Unit2’s header file. C++ Builder provides another technique. After making sure that either Form1 displays on the screen or a Unit1 tab is displaying, on the main menu, you can click File -> Include Unit Hdr… From the Use Unit dialog box, you would click the name of the unit you want to include to the current unit and click OK. Borland C++ Builder will automatically add the right and selected header to the client.

Practical Learning Practical Learning: Using the Form’s Events

 
  1. Create a new project with its default form
  2. On the Object Inspector, click Caption and type Rapid Application Development
  3. Click Name and type frmMain
  4. To add another form to your application, on the View toolbar, click the New Form button 
  5. Click the Name field and change it to frmSecond
  6. As the new form is still selected, double-click in its middle to initiate its OnCreate event.
  7. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmSecond::FormCreate(TObject *Sender)
    {
    	Width = 405;
    	Height = 350;
    	Caption = "I know you called me!";
    }
    //---------------------------------------------------------------------------
  8. To display the main form, on the main menu, click View -> Forms…
     
  9. On the View Form dialog box, click frmMain and click OK
  10. To include the header of the other form, on the main menu, click File -> Include Unit Hdr…
  11. From the list, Unit2 should be selected already, otherwise click it
    Click OK
  12. On the Object Inspector, click the Events tab and double-click the event field of the OnDblClick field
  13. Implement the event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::FormDblClick(TObject *Sender)
    {
    	frmSecond->ShowModal();
    }
    //---------------------------------------------------------------------------
  14. To test the program, press F9
  15. Move the form from its current position by dragging its title bar
  16. To call the second form, double-click in the middle of the form
  17. After viewing the form, close it. Also close the main form
  18. To add another form to your application, on the main menu, click File -> New -> Form
  19. Change the name of the new form to frmFloater
  20. On the Object Inspector, click the OnCreate name and double-click the event field
  21. Implement the event as follows:
     
    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop
    #include "Unit3.h"
    // Include the dependent header file
    #include "Unit2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TfrmFloating *frmFloating;
    //---------------------------------------------------------------------------
    __fastcall TfrmFloating::TfrmFloating(TComponent* Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TfrmFloating::FormCreate(TObject *Sender)
    {
    	// The appearance should be that of a floating window
    	BorderStyle = bsToolWindow;
    	// Keep this floating always on top
    	FormStyle = fsStayOnTop;
    	// Change the form's background color
    	Color = TColor(RGB(202, 238, 255));
    	// Make sure this window aligns with the top-left
    	// corner of the calling form
    	Top = frmSecond->Top;
    	Left = frmSecond->Left;
    	// Set the dimensions of the window
    	Height = 325;
    	Width = 124;
    }
    //---------------------------------------------------------------------------
  22. We will call the floating window from the second form. On the View toolbar, click the View Unit button
  23. On the View Unit dialog, click Unit2
     
  24. Click OK
  25. Press F12 to display the second form
  26. Press Alt + F11 to call the Use Unit dialog. Double-click Unit3
  27. On the Object Inspector, double-click the OnClick event
  28. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmSecond::FormClick(TObject *Sender)
    {
    	frmFloater->Visible = !frmFloater->Visible;
    }
    //---------------------------------------------------------------------------
  29. To test the program, press F9
  30. To display the second form, double-click the main form
  31. To display the floating form, click the second form. Notice that the floating window appears
  32. Move the second form and try to position it on top of the floating window. Notice that the floating window is always on top of the second window
  33. Click the second form again. Notice that the floating form reappears
  34. Click the second form again to display the floating window. Make sure the floating window displays
  35. Close the second form and close the first form also
  36. Display the second form
  37. On the Object Inspector, double-click the event field of OnClose
  38. Implement it as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TfrmSecond::FormClose(TObject *Sender, TCloseAction &Action)
    {
    	if( frmFloater->Visible )
    		frmFloater->Close();
    }
    //---------------------------------------------------------------------------
  39. Press F9 to test the program
  40. Display the second form
  41. Click the second form to display the floating window
  42. Close the second form. Notice that the floating window has been closed
  43. Close the main form

Dynamic Forms

Besides designing a form visually, sometimes this will not be possible. You may have to create the form dynamically. To create a form dynamically, declare a pointer to a TForm class. If you want to quickly use a form in a function or an event, you can create it easily. There are two options you have.

If you want to create a duplicate of the form you already have, you can use it as the base class and simply create an instance of the form using the new operator. When dynamically creating a form, you must specify the object or form that "owns" the form. If you are creating a duplicate of the form, set the owner as the current form or the this pointer. The owner is provided to the constructor. For example, to create a duplicate form using a form’s OnDblClick event, you can implement the event as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDblClick(TObject *Sender)
{
	TForm1* Former = new TForm1(this);
}
//---------------------------------------------------------------------------

The problem with a duplicate is that, unless you go through a big deal of code writing, every time you do anything on the form, the duplicate produces the same action. Therefore, the second option consists of creating a fresh form. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDblClick(TObject *Sender)
{
	TForm* Former = new TForm(this);
}
//---------------------------------------------------------------------------

The biggest problem with a locally created form is that it is available only in the event or the function in which it is created. If you try to access it outside, you would receive an error. If you want a form to be available to more than one event or function, you must create it in a header file of an existing form. If you want the form to be available outside of the parent form that “owns” the header file, you must declare it in the public section. Otherwise, you should declare it in the private section:

//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
private: // User declarations
	TForm* Comet; // A dynamically created form
public: // User declarations
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

After declaring the form, you can use the constructor of the host form to initialize the dynamic form. This is done by using the new operator and initializing the TForm class with the this pointer. Here is an example:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Comet = new TForm(this);
}
//---------------------------------------------------------------------------

Customizing Dynamic Forms

Whatever technique you use to create your form, you can set its properties using code. The most basic thing you should do is to display it. This is done using the TForm::Show() method. If the form was created locally, you must display it in the function or event where it was created:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDblClick(TObject *Sender)
{
	TForm* Former = new TForm(this);
	Former->Show();
}
//---------------------------------------------------------------------------

After creating and using a form, you should make sure the memory allocated to it is regained. The Borland C++ Builder compiler can take care of cleaning your dynamic controls when the application exists. Otherwise, you can delete it manually:

delete MyForm;

Furthermore, to avoid any memory leak, you can reclaim the dynamically allocated memory by assigning NULL to the deleted object:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDblClick(TObject *Sender)
{
	TForm1 *Cosmos = new TForm1(this);
	Cosmos->ShowModal();

	delete Cosmos;
	Cosmos = NULL;
}
//---------------------------------------------------------------------------

Imagine you dynamically declare an object, such as a form, as follows:

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
...
private: // User declarations
	TForm* Fake;
public: // User declarations
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------

We have seen that you can initialize it in the constructor of the form that owns your object:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Comet = new TForm(Form1);
}
//---------------------------------------------------------------------------

Once the dynamic object has been initialized you can display it any time you choose. For example, you can do this when the user double-clicks in the primary form:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDblClick(TObject *Sender)
{
	Comet->Show();
}
//---------------------------------------------------------------------------

Over all, the C++ Builder compiler takes care of deleting the dynamic object when the form that owns it is closed. If you want to make sure that your dynamic object is destroyed, you can use the delete operator as seen above. In reality, since you can use your judgment to decide when the object would be displayed, when the form that owns it is closed, before deleting the dynamic object, you can first find out if the object was really created. This can be performed with a simple if statement.

The best place to destroy a dynamically created object that a form owns is when the form is destroyed. When a form is being closed, it fires the OnDestroy event. This is the favorite place to perform any housecleaning necessary and related to the form. Based on this, you can destroy the above Fake object as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
	if( Fake )
	{
		delete Fake;
		Fake = NULL;
	}
}
//---------------------------------------------------------------------------
 
Previous Copyright © 2005-2007 Yevol Next