Mirror

Creating visual objects at run-time (Views: 704)


Problem/Question/Abstract:

Sometimes it's necessary to create a visual object, like a button or a label, at run time. Here I'll show how to do it with a simple example.

Answer:

To explain how to create a visual object at run-time, there's some simple notions that is necessary to understood. I'll try to explain it in a simple and fast way (so don't bother with any "less accurate" information). Simplifying things, objects have two things: properties and methods. A visual object is not different, it has properties, methods and can act on event handling.

A visual object's life cycle is just like any other object life cycle, it must be created, will "live" and at the end will die. Follwoing this three basic life cycle steps:

When creating a visual object, it's necessary to say who will be the parent, who will have it has a child. Example: when deploying a TPanel on a TForm, the TForm is the TPanels' parent, when deploying a TLabel on the TPanel, the TPanel is the TLabels' parent.
To give the object some "life", it's necessary to code the answer to an event. Example: the OnKeyUp event on a TForm tells the TForm what to do when the user releases a key.
When the object is no longer needed, it should be removed. Example: when you have a TLabel that you no long need, you delete it.

So, let's take a simple case to exemplefy this. Let's create a TButton and give it some life.

Start a new project, name your main form as "Form1" and specify these private variables:

MyButton: TButton;
IsAlive: Boolean;

Deploy a TButton on Form1, caption it as "Manage Button" and on the OnClick event write the following code:

// create the button
MyButton := TButton.Create(Form1);
with MyButton do
begin
  // setting the buttons' parent
  Parent := Form1;
  // setting the alignment and size
  Top := 50;
  Left := 10;
  Width := 100;
  // showing it
  Caption := "&It Works!";
  Visible := True;
end;

This creates the button when the "Manage Button" is pushed. Run the application and click the "Manage Button".

This is not really usefull util the button created ar run-time actually do anything, so let's give it life. Let's build a procedure able to respond to a OnClick event. On your Form1 private declaration write:

procedure MyButtonOnClickEvent(Sender: TObject);

and write the following code for it:

procedure TForm1.MyButtonOnClickEvent(Sender: TObject);
begin
  ShowMessage("Well, it really works!");
end;

How do we know this will work? Well, if you check the TButton help, you will see that the OnClick event has the same signature as the MyButtonOnClickEvent that was just coded. Whenever you need to build an event, check the documentation on that object's event and make a procedure with the same signature.

Now let's make the MyButtonOnClickEvent the OnClick event of the button, just add

OnClick := MyButtonOnClickEvent;

to the code, it should look like this now:

// create the button
MyButton := TButton.Create(Form1);
with MyButton do
begin
  // setting the buttons' parent
  Parent := Form1;
  // setting the alignment and size
  Top := 10;
  Left := 10;
  Width := 100;
  // making it respond to the OnClick event
  onClick := MyButtonOnClickEvent;
  // showing it
  Caption := "&It Works!";
  Visible := True;
end;

Now run it, click the "Manage Button" and then click the "It Works!" button! ;)

Now that the button has some "life", all it needs is to "die" to have a full life cycle. So, let's kill it by calling the standard destructor. Let's change the "Manage Button" code to create and destroy the MyButton button:

if IsAlive = False then
begin
  // create the button
  MyButton := TButton.Create(Form1);
  with MyButton do
  begin
    // setting the buttons' parent
    Parent := Form1;
    // setting the alignment and size
    Top := 10;
    Left := 10;
    Width := 100;
    // making it respond to the OnClick event
    onClick := MyButtonOnClickEvent;
    // showing it
    Caption := "&It Works!";
    Visible := True;
  end;
  IsAlive := True;
end
else
begin
  MyButton.Free; // kills the button
  IsAlive := False;
end;

The IsAlive flag will tell us if the button is alive or not. To be positive that this has no faults, the IsAlive variable should be initialized, let's fo it on Form1's OnShow event:

IsAlive := False;

Now run the application. Click the "Manage Button", click the "It Works!" button, click the "Manage Button" again.
Simple, isn't it ? :)

<< Back to main page