Forms Messages and Events
|
Creating a Form
|
When an application made of a form is launched, the
form must be created to display to the user. As the form gets created, it
initializes 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 during design, the code of this
event would be created and made ready for you.
|
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.
When two or more forms are running on the computer, only
one can receive input from the user. That is, only one form 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 color of the title
bar is specified by the operating system and you can check it in the
Appearance Settings from the Control Panel:
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 activate a form, the user can click
its button on the task bar. Another option includes pressing Alt + Tab
continuously until the main form of the application is selected. When a form
has been activated, it fires the OnActivate() event. OnActivate()
is a TNotifyEvent type of event. To let you get a handle of the form
that is active from the application, the TApplication class
provides the ActiveFormHandle property:
__property HWND__ * ActiveFormHandle = {read=GetActiveFormHandle};
To let you find out whether a certain form is currently
activated or it is currently the active one, the TCustomForm
provides a read-only Boolean property named Active:
__property bool Active = {read=FActive};
If an application contains at least two forms and if
both are currently displaying, the form behind the first is referred to as
the inactive form. The title bar of that form uses a color set by the
operating system and named the Inactive Window.
When a user clicks a form to active it, that form comes
to the front and the other is sent to the back. The other form is said to be
de-activated. When this is done, that form fires an OnDeactivate()
event.
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.
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.
To let the users close a form, the operating system
provides the system Close button (
//--------------------------------------------------------------------------- void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose) { } //---------------------------------------------------------------------------
The OnCloseQuery event is of type
TCloseQueryEvent:
__property TCloseQueryEvent OnCloseQuery;
This event allows you to take some action before the
form is actually closed. The CanClose argument allows you to decide whether
you really want the form to be closed or not. If you want to prevent the
form from being closed, set the CanClose argument to False. Consider the
following example:
//--------------------------------------------------------------------------- void __fastcall TForm1::FormCloseQuery(TObject *Sender, bool &CanClose) { CanClose = False; } //---------------------------------------------------------------------------
In this case, when the form displays, if user clicks the
system Close button, the form will not be closed (you will have to give the
user another way to close the form).
When the user has finished using a form, he must be able
to close it. To let you do this, the TCustomForm class
provides a method named Close. Its syntax is:
void __fastcall Close();
When this method is called:
As a 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:
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.
Unless you are creating some type of a simple message
box, a form usually has many controls so that a user can interact with it to
create or get values. To use a control, the user usually has to click it or
continually press Tab to activate a particular control. This gives focus to
it. From the form's point of view, to give focus to a control, the
TCustomForm class provides the FocusControl() method. Its
syntax is:
void __fastcall FocusControl(Controls::TWinControl * Control);
This method takes one argument as a pointer to the
control that must receive focus. Of course, you must pass a reference to a
control that exists on the form. If you pass the name of a control that
cannot be found, you would receive an error.
|
When you create a new VCL Forms application, you get a
default form. If one form is not enough for your application, you can add as
many as necessary. To add (or to create) a (new) form:
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 add more than one form to a project, the form
that was created first is referred to as the main form. If/When you execute
the application, that main form would display first. If you want, you can
specify what form should come up first. To assist you with this, the
TApplication class provides a property named MainForm:
__property Forms::TForm * MainForm = {read=FMainForm};
To visually specify the default form on an application,
on the main menu, click Project -> Options... In the left list, click Forms.
On the right side, click the arrow of the Main Form combo box to display the
list of forms of the current application:
Select the name of the desired form and click OK.
To programmatically specify the default form, in the
project file of your application, arrange the sequence of form creation so
that the desired form is on top. Here is an example:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
USEFORM("Unit2.cpp", Form2);
USEFORM("Unit3.cpp", Form3);
USEFORM("Unit4.cpp", Form4);
//---------------------------------------------------------------------------
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
Application->Initialize();
Application->MainFormOnTaskBar = true;
Application->CreateForm(__classid(TForm3), &Form3);
Application->CreateForm(__classid(TForm1), &Form1);
Application->CreateForm(__classid(TForm2), &Form2);
Application->CreateForm(__classid(TForm4), &Form4);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
Because TApplication::MainForm is a
read-only property, you cannot change it with code. You can only find out
what form is set as the default by getting the value of this property. Here
is an example:
//---------------------------------------------------------------------------
void __fastcall TForm4::Button1Click(TObject *Sender)
{
ShowMessage(L"The main form is " + Application->MainForm->Name);
}
//---------------------------------------------------------------------------
You can use this information as you see fit.
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
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. C++Builder
will automatically add the right and selected header to the client.
|
No comments:
Post a Comment