Technical Information Database TI1069D.txt Creating Dynamic Components at Runtime Category :General Programming Platform :All Product :Delphi 1.0 Description: Using Delphi forms and components is simple. When coupled with the object inspector, controlling those objects requires little effort. Creating these types dynamically is also not difficult. This document is intended to give you some tips and hints on how to make dynamic component work for you. (please note this term "dynamically" is subjective, behind the scenes, Delphi creates all objects dynamically. The information presented herein is for the programmer setting creation/properties/deletion the given type at run time) All types (a form or a component) can be created dynamically. To do this, one needs to put a declaration in the VAR section of their code. This does not create an instance of the object, it creates a pointer. This pointer resides in the data segment (if the variable is declared globally) or the stack (if the variable is declared local to a procedure or function). In order to instantiate this class, you must call the constructor. This will allocate memory in the computers global heap for the class instance. Trying to access the component before allocating memory will produce a general protection fault. The Create() constructor is a class method descended from the TObject Class. Create() returns a pointer. This method may or may not take one or more parameters. For most components (all objects which descend from TComponent are referred to as components), the constructor takes one parameter, the "owner" of type TComponent. When dynamically creating a component, setting the Owner to "Self" is the most common practice. If you are in one of a form's methods, "Self" refers to that form in that context. If the owner is a valid object, freeing that object will also free the "owned" component. Another common parameter is "Application". This might be used for a visual component that will not be displayed to the program's users. However, most components do not require that you set a specific owner, so it is not uncommon to set the owner to Nil. Keep in mind, though, that you will not be able to change the owner afterwards. If you do pass Nil to a component's constructor, you must remember to call that component's Free method when you are through using the component. After creation, but before they can be displayed, windowed components (those descending from TWinControl) require the Parent property to be set. At the time you set the Parent property, it's usually also a good time to set other properties of this components instance, including event handlers (ie, Width, Color, OnClick). Event handlers are identical to those specified in the object inspector. Simply set the component's property name for the event you want to handle to name of the event handler method you want invoked. Example 1 below would call the method called "myclick" whenever the button is clicked. Please note this method will be sent the appropriate parameters, and its incoming parameter list must be exact. Example 1: var b1 : TButton; begin . . . b1 := TButton.Create(Self); with b1 do begin Left := 20; Top := 20; Width := 90; Height := 50; Caption := my button'; Parent := Form1; OnClick := MyClick; { a procedure I defined somewhere else } end; . . . end; The next example demonstrates how to create a button at run time by clicking a predefined button. Note the different way the button has been created. Either way would work. Also note the buttons that are created are not freed in this code, they will be freed when the form is released. unit Unit1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure myClick(Sender: TObject); end; var Form1: TForm1; const i : integer = 0; implementation {$R *.DFM} procedure TForm1.myClick(Sender: TObject); begin with Sender as TButton do Self.Caption := ClassName + ' ' + Name; end; procedure TForm1.Button1Click(Sender: TObject); begin with TButton.Create(self) do begin Left := 20; Top := 30 + i; Width := 120; Height := 40; Name := 'ThisButton' + IntToStr(i); Caption := 'There' + IntToStr(i); OnClick := MyClick; { a procedure I defined somewhere else } Parent := Form1; end; {end with} inc(i, 40); end; {end button1.click} end. Reference: 7/16/98 4:34:00 PM
Last Modified: 01-SEP-99