0% found this document useful (0 votes)
11 views12 pages

Chapter 13 Dynamic Objects

Chapter 13 discusses dynamic object instantiation in programming, particularly in the context of creating and destroying components during runtime. It provides examples of how to implement dynamic components, such as panels and buttons, in a Delphi application, including handling their visibility and memory management. The chapter also includes activities for creating dynamic images and managing multiple dynamic components, emphasizing the importance of parent-child relationships in component hierarchy.

Uploaded by

Mekyla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views12 pages

Chapter 13 Dynamic Objects

Chapter 13 discusses dynamic object instantiation in programming, particularly in the context of creating and destroying components during runtime. It provides examples of how to implement dynamic components, such as panels and buttons, in a Delphi application, including handling their visibility and memory management. The chapter also includes activities for creating dynamic images and managing multiple dynamic components, emphasizing the importance of parent-child relationships in component hierarchy.

Uploaded by

Mekyla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Chapter 13: Dynamic objects

Introduction
In some applications, programmers have to use many components on the interface. (Think for
example about all the images which are used in games such as solitaire.) Every component takes up
space in memory of the computer. It also occupies space on the Form. Therefore programming
languages provide the option for programmers to also create a component when the program is
already running. This can be very useful, for example when games applications are developed, where
images can be created as the game progresses, and destroyed again when there is no longer any use
for the these images. When a component is created during run-time of an application, it is called
dynamic instantiation of an object.

Dynamic components on a Form


Create a dynamic component which will be displayed
once, then destroyed again
Let us look at an example where a dynamic component can be used. Run the program
frmCashRegister_p.exe which can be found as part of the data for this chapter.

When the program starts, only on Button [Login] is visible. When the user clicks on the Button, the
[Login] Button disappears, and a Panel containing a greeting, as well as a [Start] Button appear.

Once the user has read the message, the [Start] Button can be clicked to display the actual interface
of the program. When the [Start] Button is clicked, the Panel containing the greeting should
disappear. In the explanation of the program which follows, we will show you how the Panel can be
created and destroyed again while the programming is executing (dynamically instantiated). (The
Buttons are just displayed or hidden using the Visible property).

The TOE chart for this program looks as follows:

1
Task Object Event
1. Make btnLogin visible frmCashRegister OnShow
2. Make btnStart invisible
1. Make btnLogin invisible btnLogin Click
2. Make btnStart visible
3. Dynamically instantiate pnlGreet
4. Set all the properties of pnlGreet
1. Make btnStart invisible btnStart Click
2. Destroy pnlGreet
3. Make the components of the program visible

The program to do this looks as follows:

type
TfrmCashRegister = class(TForm)
These are the names for each
btnStart: TButton;
component the programmer places on
btnLogin: TButton; the Form. Delphi automatically creates
procedure btnStartClick(Sender: TObject); these variables.
procedure btnLoginClick(Sender: TObject);
procedure FormShow(Sender: TObject);
private
The programmer declares a variable
pnlGreet : TPanel ; (pnlGreet). This variable will be used to
public refer to the Panel object which will be
end; instantiated dynamically. It is declared as
var a variable with class scope, because two
different event handlers will need to have
frmCashRegister: TfrmCashRegister;
access to this component (the Panel).
implementation
{$R *.dfm}

procedure [Link](Sender: TObject);


begin
[Link] := true ; When the program starts, only Button [Login] must be
[Link] := false ; visible.

end;
The Panel is created (instantiated) by
calling the Create method of the TPanel
procedure [Link](Sender: TObject);
class. The value in brackets indicates that
begin
the Form called frmCashRegister must be
[Link] := False ; the owner of the Panel.
[Link] := True ;
pnlGreet := [Link](frmCashRegister);

The Form is assigned as the parent of


[Link] := frmCashRegister ; pnlGreet. You can also refer to pnlGreet as:
‘The child of frmCashRegister’.
2
with pnlGreet do
begin
Name := 'pnlGreet' ;
Caption := 'Welcome to the Licky Chicky shop. Click on Start.';
Left := 250 ;
Top := 50 ; The properties of the component
Width := 600 ; must be set through programming
Height := 100 ; code after it has been created.
Color := clSkyBlue ;
end ;
end;

procedure [Link](Sender: TObject);


begin
[Link] := true ; When Button [Start] is clicked, the interface should
[Link] := false ; appear (statically built on a Panel), and the dynamic
[Link]; Panel should be set free – this will free the memory it
end; occupied, and make it disappear from the Form.

Note:

x A component must have an owner and a parent. Delphi takes care of this automatically when
you choose a component from the Palette and drop it on the Form. With a dynamic component
you have to indicate it specifically.
x The owner of a component controls the existence of the component. When the owner is
destroyed, all the components it owns are also destroyed. You can also destroy a dynamic
component explicitly before its owner is destroyed.
x The parent of a component controls the display of the component. The parent makes the
component visible, and it controls the format (the way the child component is displayed). For
example:
o Certain properties of the parent can be inherited by the child automatically e.g. the
Font.
o When the Left and Top properties of a child component is set, it is relative to the parent
component. For example if an Image is the child of a Panel, and the Left property of the
Image is set to 50, it will be 50 pixels from the side of the Panel, not from the side of the
Form.
o (If you do not set the Parent property, the component will not be visible.)
x You can also use the Destroy method to free the memory occupied by a dynamic object,
however, it is safer to use the Free method because:
o If you use Destroy on an object that does not exist anymore, you will receive an Access
violation error. The Free method will always test if an object does exist, only if it does
exist the object will be destroyed.

3
Activity 1: Create a dynamic Image

x Open the program frmCashRegister_p.dpr which has been supplied as data for the chapter.
Add code to create a dynamic image which will be instantiated and destroyed at the same
time as the greeting.
o The image you want to load onto the Image component must be stored in the same
folder as the program.
o The following is an example of an instruction to load a picture into the dynamically
instantiated Image component (the names you choose for the Image and the file
may be different).

[Link]('[Link]') ;

x Run the program, and then change


The child component (the Panel) will inherit the
the type of the Font of the Form in
Font from the parent component (the Form).
the Object Inspector. Run the
program again.

If you want to use a file of another format such as .jpg, you have to tell Delphi where to find the
code needed to decode the format. You do this by adding the name of the library (unit) where the
code is stored to the uses clause at the beginning of the Form’s Unit.

unit frmCashRegister_u;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls,
StdCtrls, jpeg;

Create the same dynamic component more than once in


a program
In some applications you may want to make dynamic
components appear and disappear a number of times. Look
at the following example:

A school sells tickets for a show. The cost of each ticket is


R50.00. After the show, people can attend a dinner. If the
[Attend dinner] CheckBox is ticked, two more components
should appear where the user can enter the number of
adults and the number of children which will attend.

4
These two components are LabeledEdits (of
type TLabeledEdit). They will be created in the
When Button [Next customer] is clicked, the
event handler of the OnClick event of the
following should happen:
CheckBox.
x The memory occupied by each
component (the LabeledEdits) should be released using the Free method.
x The variables referring to the components should be cleared.

This can be done as follows:

[Link] ; // Free the memory space

edtNumAdults := nil ; //Clear the variable name

When the user clicks on Button [Buy], the event handler should read the values from the
LabeledEdits, and calculate the final cost. However, the program should not try to read a value from
the dynamic components if they do not exist. For this example, there are two ways to ensure the
LabeledEdits will only be accessed if they do exist:

Method 1: If the CheckBox is checked, the LabeledEdits will exist, because


if [Link] then the OnClick event handler of the CheckBox creates the
LabeledEdits.
begin

iNumAdults := StrToInt([Link]) ;

iNumChildren := StrToInt([Link]) ;

end

Method 2:
An assigned function can be used to determine if one of
if assigned(edtNumAdults) then
the LabeledEdits exists.
begin

iNumAdults := StrToInt([Link]) ;

iNumChildren := StrToInt([Link]) ;

end

5
Activity 2: Create a dynamic component - use it more than once in the
program

Write a Delphi program for the previous example making use The interface for activity 2 is
of dynamic components. The total cost should be displayed
available with the data for the
when the user clicks on Button [Buy]. The cost of one ticket
chapter.
for the show is R50.00, a dinner ticket for an adult costs
R100.00, and a dinner ticket for a child costs R25.00.

Ensure your program includes the following:

x If a user clicks the CheckBox the dynamic components (LabeledEdits) should appear. But if
the user changes his mind immediately, and ‘unticks’ the CheckBox, the LabeledEdits should
diappear again.
x When the [Next customer] Button is clicked, all the components should be cleared, and the
focus placed in the SpinEdit (number of tickets).

Child components containing their own


children
In this example a dynamic Panel is created on a Form. The Panel then acts as a parent component
when an Image and a Label is created dynamically.

Parent and owner of


Parent and owner of

child of MyImage

frmPictures MyPanel
child of
MyLabel
child of

Parent and owner of

You can open the file frmPicture_p.dpr provided as data for this chapter to review this program.

6
type
TfrmPicture = class(TForm)
btnShow: TButton;
btnDestroy: TButton;
procedure btnShowClick(Sender: TObject);
procedure btnDestroyClick(Sender: TObject);
private
{ Private declarations }
MyPanel: TPanel;
MyImageOnPanel: TImage;
MyLabel: TLabel;
public
{ Public declarations }
end;

var
frmPicture: TfrmPicture;

implementation
{$R *.dfm}

procedure [Link](Sender: TObject);


begin
MyPanel := [Link](frmPicture);
MyLabel := [Link](MyPanel);
MyImageOnPanel := [Link](MyPanel);

with MyPanel do
begin
Parent := frmPicture;
Left := 20; The Left and Top properties are
Top := 100; relative to the parent (frmPicture)
Width := 350;
Height := 350;
Caption := '';
TabOrder := 0;
Color := clBlack;
end;
with MyImageOnPanel do
begin
Parent := MyPanel;
Left := 50;
Top := 50;
Width := 250;
Height := 260; MyPanel is the parent of the
[Link]('[Link]');
Stretch := True; components MyImageOnPanel and
end; MyLabel. Therefore these Left and
with MyLabel do Top properties are relative to
begin
Parent := MyPanel; MyPanel.
Left := 120;
Top := 10;
Width := 30;
Height := 20;
Caption := 'The flower';
[Link] := [fsBold, fsUnderline];
[Link] := clWhite;
end;
end;

7
procedure [Link](Sender: TObject);
begin
[Link];
MyPanel := nil ;
end;

end.
x MyPanel is a child object created on frmPicture.
x Both MyImage and MyLabel are child objects of the MyPanel component. Therefore when
you destroy the MyPanel component you will destroy both child objects as well. Since all of
the components are child objects of frmPicture they will all be destroyed when frmPicture is
closed.

Activity 3: Create parent and child

1. A file [Link] contains 30 ID numbers. Write a program that will read these numbers from the
text file into an array of strings. The interface of the program should have two Buttons.

x When the [Count Gender]


Button is clicked, a Panel
containing two Labels
should be instantiated
dynamically. The number
of males and the number of females should be displayed on the Labels.
x When the [Calculate Ages] Button is clicked, the age indicated by each ID number should
be displayed in a RichEdit.
(The age the person will
become in the current
year.) The RichEdit
should be created
dynamically.

Ensure your program can handle the


following:

x A user may click on the same Button twice.


x A user may click on any of the Buttons first.

2. Create a Delphi program to play the game Rock – Scissors – Paper. The interface of the
program is provided as data for the chapter. When the user clicks on the Button [Show the
rules of the game], a Panel with
other components should be created
dynamically to display the rules of
the game. When the user clicks on
any Button, Image, RadioButton or
the Form, the Panel and its children
should disappear.

The interface for activity 3.2 is


available with the data for the
chapter. 8
Binding an event handler to a dynamically
instantiated component
In the previous examples the applications just displayed the dynamic components. However, in some
application you may want to be able to interact with the components, e.g. click on a Button. You can
write a procedure (method of the class of the Form), and link it to a dynamic object so the procedure
can act as the event handler for the component. In the following example we will create a dynamic
component – a Button – and create an OnClick event handler for the Button.

The scenario is as follows: A movie theatre


provides prizes which can be won through a
lucky draw if a customer buys more than 10
tickets.

When the user clicks on the [Buy] Button, a


Button [Draw] and a label will be created
dynamically. The customer will have three
chances to draw a prize. The [Draw] Button must have an event handler to manage the display en
selection of the prizes.

The event handler is created as follows:

You need to write the declaration for the event handler of the dynamic Button yourself. (The
definitions of the other components’ event handlers are created by Delphi automatically.) You can
choose any name for the event handler. We place the event handler in the private section of the
class so it is clear that it was created by the programmer. You can also place it with the other event
handlers above the private section. An event handler needs a parameter of type TObject.

When you press <Ctrl> <Shift> <c>, Delphi will provide a framework for the event handler, and you
can then complete the code.

procedure [Link](Sender: TObject);


const
arrPrizes : array[1..10] of string =
('R200 Gift voucher at Exclusive books', 'R150 MTN air time voucher',
'R250 cash', 'Two movie tickets at NuMetro',
'Six large Cokes', 'Three large Pop Corns',
'Gift bag of chocolates (R100)', 'Gift bag of chocolates (R250)',
'R250 Cell C air time voucher', 'R150 cash') ;
9
var
iNumDraws, iPrizeNumber : Integer ;
cAnswer : char ;
sPrize : string ;
begin
iNumDraws := 0 ;
Randomize ;
repeat
inc(iNumDraws) ;
iPrizeNumber := Random(10) + 1 ;
sPrize := arrPrizes[iPrizeNumber] ;
[Link] := sPrize ;
cAnswer := UpCase(InputBox(
'Keep the prize or draw again','Are you happy with your prize? <Y/N>', 'Y')[1]) ;
until (cAnswer = 'Y') OR (iNumDraws = 3) ; ;
if (iNumDraws = 3) AND (cAnswer = 'N') then
ShowMessage('You already had 3 chances. You receive the ' + sPrize + ' as prize')
else
ShowMessage('You receive the ' + sPrize + ' as prize');
[Link] := false ;
[Link] := true ;
end;

Activity 4: Bind an event handler to a dynamically instantiated component

The executable file for the previous example is provided as The interface for activity 4 is
data for this chapter. Run the program, and then create a available with the data for the
Delphi program to duplicate the program. chapter.

Making use of dynamic, invisible objects


The TStringList class
A very useful dynamic object to make use of, is an instantiation of the TStringList class. Such an
object will be able to store a number of strings (similar to a ListBox – but the the object is not visible
during run-time). It therefore acts as an array of strings. The TStringList class provides a number of
methods which can manipulate the strings contained in the object. Examples are:

Procedure AddStrings(Strings: TStrings) ;


Procedure Delete(Index: Integer) ;
Procedure Exchange (Index1: Integer; Index2: Integer)
Procedure Sort ;
Function IndexOf(const S: String) : Integer ;
10
Procedure SaveToFile(const FileName : String) ;
Procedure LoadFromFile(const FileName : String) ;

The property Strings contains the strings itself and works similar to the Items property of a ListBox or
RadioGroup.

Activity 5: Use a TSringList object to manipulate strings

A program with the following interface is supplied


as part of the data for this chapter:

Complete code for the event handlers of the


OnClick events of each Button. Make use of a
dynamic object of type TStringList and the methods
of the class TStringList.

[Read data from the text file]:

x Use the LoadFromFile method to load data from the text file [Link] into the
TStringList object.
x Both the class TStringList and the RichEdit has a Text property. You can assign the Text
property of the StringList to the Text property of the RichEdit to transfer all the strings to the
RichEdit in one statement.
The interface for activity 5 is
[Sort the list of strings]: available with the data for the
x Use the Sort method. chapter.

[Shuffle the strings]:

x Use the Exchange method. You can randomly exchange a number of lines with one another.

[Write string back to file]:

x Use the SaveToFile method to save the content of the TStringList back to the text file
[Link] .

A speech recognition object The use of a speech recognition object


is not part of the curriculum. However,
Windows has a speech recognition application.
it may be useful when you create your
Windows also provides an API (Application
PAT.
Programming Interface) which allows other applications
such as Delphi to communicate with the speech recognition application. The following code
demonstrates how to create an OLE (Object Linking and Embedding) object which will be able to
communicate with the Windows speech recognition application. Some of the code just forms part of
the linking process, and it will not be explained.

11
uses
{existing uses},ComObj; Add the ComObj unit to the uses-clause.

procedure TForm1.Button1Click(Sender: TObject);


var
Voice: OLEVariant; Voice is the object which will send messages to the speech
recognition application.
begin
Voice := CreateOLEObject('[Link]'); //instantiate the object
SavedCW := Get8087CW;
Set8087CW(SavedCW or $4); The text in the EditBox edtGreet will be interpreted
[Link]([Link]); and read aloud by the speech recognition application.
Set8087CW(SavedCW);
end;

If you are using a windows version older than Vista the lines shaded in grey are not needed.

12

You might also like