Board index » delphi » Help creating Event-handlers at Run Time

Help creating Event-handlers at Run Time

Hello:

I would like to know if someone could help me out in creating an event
handler at runtime.  I am familiar with creating the component at runtime,
i.e.
var
    newbutton: Tbutton;
begin
    newbutton := Tbutton.create(self);
    with newbutton do
        begin
            name := 'button2';
            left := 100;
            top := 100;
            newbuttonparent := self;
        end;

Could someone please tell me how I would go about attaching an onclick event
handler to this button?

Most books I have referenced refer to the creation process but then fail to
explain the second necessary step, that of creating the event-handler.

Your help is greatly appreciated.

Marko
---------------
m...@sepcoinc.com

--

Marko
---------------
m...@sepcoinc.com

 

Re:Help creating Event-handlers at Run Time


(Example)

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure ButtonClick(Sender : TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ButtonClick(Sender : TObject);
begin
  ShowMessage((Sender as TButton).Name);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  NewButton : TButton;
begin
  NewButton := TButton.Create(Self);
  with NewButton do
    begin
      Name := 'Button2';
      Left := 100;
      Top := 100;
      Parent := Self;
      OnClick := ButtonClick;
    end;
end;

end.

Re:Help creating Event-handlers at Run Time


In article <e_df2.1305$9v.10815...@iagnews.iagnet.net>, "Marko"

Quote
<ma...@mtco.com> writes:
>I would like to know if someone could help me out in creating an event
>handler at runtime.  I am familiar with creating the component at runtime,
>i.e.
>var
>    newbutton: Tbutton;
>begin
>    newbutton := Tbutton.create(self);
>    with newbutton do
>        begin
>            name := 'button2';
>            left := 100;
>            top := 100;
>            newbuttonparent := self;
>        end;

>Could someone please tell me how I would go about attaching an onclick event
>handler to this button?

You must remember that an event handler is a property like any other data for
that class, but the property holds the pointer to a procedure. As with most
Delphi references, you reference it by name, and Delphi sorts out getting the
pointer from the name.

Also the property is of an appropriate type, for an OnClick the type is
TNotifyEventdeclared as "procedure (Sender: TObject) of object". "of object"
means that it must be a method of an object (ie Delphi pushes a hidden
parameter of a pointer to the instance of the object onto the stack when it
calls the handler). The parameter Sender (which is applied by the object code)
is the apropriate descendant of TObject (TButton in your case) which causes the
event, and must be type-cast by your event handler code (to the actual type of
the Sender) to enable the compiler to allow access to any properties or methods
of the sender which are in the descendant but not in TObject.

Alan Lloyd
alangll...@aol.com

Re:Help creating Event-handlers at Run Time


Gentlemen:

Thank you for your help on the event-handler question.  A second part of this event handler question
is how to call a property that is created in the runtime environment.

An example is that I wish to create 3-labels.  Initially when these labels are created I want them
to be invisible.  I am then sequentially making the labels visible with a timed function.

Presently I have declared the labels to be created variables in the interface portion of the form.
i.e

Var
    label1,label2,label3 : Tlabel;

This seems to work, however is there a way to declare these labels at runtime and still call a
property change at runtime, and allow the compiler to compile because the property being changed has
not yet been created?

Quote
>---------------
>m...@sepcoinc.com

Re:Help creating Event-handlers at Run Time


Quote
Marko wrote:

> This seems to work, however is there a way to declare these labels at runtime and still call a
> property change at runtime, and allow the compiler to compile because the property being changed has
> not yet been created?

Yes. Best not to create the labels there, but as children of the form.

try this

procedure TForm1.CreateLabel;
var
   NewLabel;

begin
NewLabel:=TLabel.Create(Form1);
{Set up size + position of label}
NewLabel.Tag:=1234; {Special tag to be able to discriminate our labels}
end;

Although once this procedure has finished, there's no variable poitning
to the label, it still belongs to the form, and you can access it
through the forms component property:

procedure TForm1.SetLabelCaption;

var
   ComponentNum:integer;
   MyComponent:TComponent;

begin
for ComponentNum:=0 to ComponentCount do
begin
     MyComponent:=Components[ComponentNum];
     if (MyComponent is TLabel) and MyComponent.Tag=1234 then
     begin
          MyComponent.Caption:='Foo'; {Put your caption here}
     end;
end;
end;

Hope this helps. You don't need to have a vairable pointing to your
label if you've created it as a child of a form... the form will keep
track of it's creation and destruction, and you can still find it
without too much trouble.

Hope this helps.

MH.

--
Martin Harvey.
Totally rewritten web pages at:
http://www.harvey27.demon.co.uk/mch24/

"ALGOL 60 was a language so far ahead of its time that it
was not only an improvement on its predecessors but also
on nearly all its successors". C.A.R. Hoare

--------------BEGIN GEEK CODE BLOCK--------------
Version: 3.12
GCS/CC d(+) s-:- a-- C+++$ UL@ P L@>++ E- W++
N+++ o-- K++ w+++$ O--- M-- V-- PS@ Y-- PGP-
t--- 5-- X-- R-- !tv b+ DI+ D+ G e++ h- r z++>---
---------------END GEEK CODE BLOCK---------------

Re:Help creating Event-handlers at Run Time


In article <7ouf2.1353$9v.11261...@iagnews.iagnet.net>, "Marko"

Quote
<ma...@sepcoinc.com> writes:
>This seems to work, however is there a way to declare these labels at runtime
>and still call a
>property change at runtime, and allow the compiler to compile because the
>property being changed has
>not yet been created?

1 I'm not sure what you mean by "declare these labels at runtime". Do you mean
"declared but not created until run-time". Declaration is only a compile-time
activity. Once compiled the names you allocate are not remembered (except via
the use of Run-Time Type Information).

2 Properties are just a data store, like any variable, and in general are
accessible at run-time and can be changed as you like (there are some
properties which are read-only). Its not that the object is created with those
properties and cannot be changed, but that the object is created, and at
creation and throughout its life referss to the properties to define its
continuing characteristics.

So you can declare a Label

var
 MyLabel : TLabel;

It and all its properties can now be referred to in code. The code in the
code's execution must not actually change or define the properties until it has
been created.

So in the forms' OnCreate event handler I can code :-

MyLabel := TLabel.Create(Self);  // the form instance is the owner
with MyLabel do begin
  Parent := Self;  // parent must be defined for MyLabel to do or be anything
  Visible := false;
  SetBounds(10, 10, 75, 25);  // define top, left, width, height
  Caption := 'This is My Label';
  Font.Color := clRed;
end;

 . . . this will create the label at form creation time.
And in a button OnClick event handler code :-

MyLabel.Caption := 'Stop It !';
MyLabel.Font.Size := 14;
MyLabel.Visible ;= true;

 . . . and it will be shown when the button is clicked.

If there is a chance that the Label might not be created when you want to later
refere to it then wrap the code in  a test for it to be created :-

if Assigned(MyLabel) then begin
  MyLabel.Caption := 'Stop It !';
  MyLabel.Font.Size := 14;
  MyLabel.Visible ;= true;
end;

Alan Lloyd
alangll...@aol.com

Re:Help creating Event-handlers at Run Time


Quote
>Yes. Best not to create the labels there, but as children of the form.

>try this

>procedure TForm1.CreateLabel;
>var
>   NewLabel;

>begin
>NewLabel:=TLabel.Create(Form1);
>{Set up size + position of label}
>NewLabel.Tag:=1234; {Special tag to be able to discriminate our labels}
>end;

Martin,

 Thank you for your assistance.  Can you explain to me why it is best to create this label as a
child of the form rather than of itself?

Mark
--------------------------
m...@sepcoinc.com

Re:Help creating Event-handlers at Run Time


Quote
Marko wrote:

> Martin,

>  Thank you for your assistance.  Can you explain to me why it is best to create this label as a
> child of the form rather than of itself?

Hmm... short question... potentially long answer.

Basically because the whole way Delphi works is to have objects that
contain other objects ad infinitum. All components can only live inside
a form, and it doesn't make a whole lot of sense to have ways of
accessing those components that aren't tied up with the form.

If you do want to have a concrete "var x,y,z:tlabel" way of getting at
things, then there's nothing to stop you putting a,b,c:tlabel in the bit
of the form declaration that says "public properties" or "private
properties": eg:

  TForm1 = class(TForm)
  private
    { Private declarations }
    a,b,c:TLabel
  public
    { Public declarations }
    d,e,f:TLabel;
  end;

But you want to make sure that if something else inherits from the form,
or uses the form, everything involved with the form also moves with the
form. If you just declare those variables in the unit, then you're
implying the those things are logically associated with the unit, and
not the form.

Sorry if this isn't a stunning explanation, but it's the best I could do
in the space available. Perhaps someone else on the newsgroup would like
to explain it better??

MH.

--
Martin Harvey.
Totally rewritten web pages at:
http://www.harvey27.demon.co.uk/mch24/

"ALGOL 60 was a language so far ahead of its time that it
was not only an improvement on its predecessors but also
on nearly all its successors". C.A.R. Hoare

--------------BEGIN GEEK CODE BLOCK--------------
Version: 3.12
GCS/CC d(+) s-:- a-- C+++$ UL@ P L@>++ E- W++
N+++ o-- K++ w+++$ O--- M-- V-- PS@ Y-- PGP-
t--- 5-- X-- R-- !tv b+ DI+ D+ G e++ h- r z++>---
---------------END GEEK CODE BLOCK---------------

Other Threads