Board index » delphi » Repointing event handler at runtime

Repointing event handler at runtime

Delphi 1.x - I want to re-assign the "ondatachange" event handler of a
ttable to a second routine at runtime. Sort of like the old interrupt
vector stuff, e.g. save current event handler, set new handler, use
new handler then restore old handler.

I've tried to setup a second routine with a similar procedure
declaration as the existing event handler (parameters the exactly the
same,  just it's "name" different) but the compiler balks at compiling
any reassignment statement I've tried. Using a pointer to save and
restore the existing handler also seemed to go nowhere.

Is this possible and if so could some one hold my hand and lead me
down the garden path for this?

Thanks in advance, pjp

p...@istar.ca

 

Re:Repointing event handler at runtime


Delphi 1.x - I want to re-assign the "ondatachange" event handler of a
ttable to a second routine at runtime. Sort of like the old interrupt
vector stuff, e.g. save current event handler, set new handler, use
new handler then restore old handler.

I've tried to setup a second routine with a similar procedure
declaration as the existing event handler (parameters exactly the
same,  just it's "name" different) but the compiler balks at compiling
any reassignment statement I've tried. Using a pointer to save and
restore the existing handler also seemed to go nowhere.

Is this possible and if so could some one hold my hand and lead me
down the garden path for this?

Thanks in advance, pjp

p...@istar.ca

Re:Repointing event handler at runtime


Can you give an example of code that won't compile?

Quote
Paul J. Poirier wrote:

> "....... but the compiler balks at compiling any reassignment statement I've tried........"

--
+---------------------------------------------------------------------+
| Stephen J. Moran, st....@silverlink.co.uk (delete 1st dot to reply) |
| "Do be do be do" - Sinatra.                                         |
+---------------------------------------------------------------------+

Re:Repointing event handler at runtime


"button1.onclick := TForm1.buttonclick1;"
should read
"button1.onclick := buttonclick1; {Form1 implicit}"
or
"button1.onclick := Form1.buttonclick1; (Form1 explicit)"

TForm1 is only the definition. Form1 (as in "VAR Form1: TForm1;") is an
instance of a TForm1 object created at runtime.

Quote
Paul J. Poirier wrote:

> ".......
>   button1.onclick := TForm1.buttonclick1;      ( won't compile }
> ......."

--
+---------------------------------------------------------------------+
| Stephen J. Moran, st....@silverlink.co.uk (delete 1st dot to reply) |
| "Let's reason with the worst that may befall" - Shakespeare.        |
+---------------------------------------------------------------------+

Re:Repointing event handler at runtime


On Fri, 26 Dec 1997 13:47:11 +0000, Steve Moran

Quote
<st....@silverlink.co.uk> wrote:
>Can you give an example of code that won't compile?

Paul J. Poirier replied:

-------------------------------------------------------------------
unit Unit1;
interface
uses
  SysUtils, WinTypes, WinProcs, Messages,
  Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

{ this is probably wrong thing to do but declare
 a second event handler ???                                 }

    procedure ButtonClick1(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

{ second handler ??? }

procedure TForm1.ButtonClick1(Sender: TObject);
begin
  form1.close;
end;

{ original handler using normal technique }

procedure TForm1.Button1Click(Sender: TObject);
begin
  MessageDlg('First time pressed.', mtInformation,[mbOk], 0);

{ now I want to point it at somewhere else }

  button1.onclick := TForm1.buttonclick1;      ( won't compile }
end;

end.

---------------------------------------------------------------------------------------------

Pretty simple really and I would think it something you'ld want to do
quite often. Absurd ot have to derive some new object and optionally
override parent!

Any ideas, p...@istar.ca

Re:Repointing event handler at runtime


In article <34a3d7f7.38805...@news.istar.ca>, "Paul J. Poirier"
<p...@istar.ca> writes

Quote
>Delphi 1.x - I want to re-assign the "ondatachange" event handler of a
>ttable to a second routine at runtime. Sort of like the old interrupt
>vector stuff, e.g. save current event handler, set new handler, use
>new handler then restore old handler.

Why not let your event handler just call either of two other procedures.
To reassign just set/unset a switch in it.

Pat
--
Pat White
email: p...@pwhite.demon.co.uk
Phone; +44 (0)1925 266113

Re:Repointing event handler at runtime


type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

{ this is probably wrong thing to do but declare
 a second event handler ???                                 }

    procedure ButtonClick1(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

Do I have to declare the event handler inside the "type" statement as
I've done above or can ANY suitable procedure (correct number & type
of parameters) do?

What restrictions apply?  For example, the event handler may not be
"known" until run-time, can it be in another "unit" or for that matter
a "dll"?

Thanks for the help, p...@istar.ca

Re:Repointing event handler at runtime


Quote
Paul J. Poirier wrote:

> type
>   TForm1 = class(TForm)
>     Button1: TButton;
>     procedure Button1Click(Sender: TObject);

> { this is probably wrong thing to do but declare
>  a second event handler ???                                 }

>     procedure ButtonClick1(Sender: TObject);

>   private
>     { Private declarations }
>   public
>     { Public declarations }
>   end;

> Do I have to declare the event handler inside the "type" statement as
> I've done above or can ANY suitable procedure (correct number & type
> of parameters) do?

> What restrictions apply?  For example, the event handler may not be
> "known" until run-time, can it be in another "unit" or for that matter
> a "dll"?

> Thanks for the help, p...@istar.ca

I'll only give the 100% answer, i.e., for the part that I have tried
myself: It can be in another unit and it can be a method of another
object, e.g., another form. Where you have declared it means it can be
seen in the dropdown list of event handlers at design time. But you
could have put it under Private or Public. The rest I would only be
giving 50% answers, e.g., I have done something similar but not exactly
the same.

Steve Moran, Flying Objects Ltd., London.

Re:Repointing event handler at runtime


On Tue, 30 Dec 1997 16:09:30 GMT, p...@istar.ca (Paul J. Poirier)
wrote:

Quote
>type
>  TForm1 = class(TForm)
>    Button1: TButton;
>    procedure Button1Click(Sender: TObject);

>{ this is probably wrong thing to do but declare
> a second event handler ???                                 }

>    procedure ButtonClick1(Sender: TObject);

>  private
>    { Private declarations }
>  public
>    { Public declarations }
>  end;

>Do I have to declare the event handler inside the "type" statement as
>I've done above or can ANY suitable procedure (correct number & type
>of parameters) do?

>What restrictions apply?  For example, the event handler may not be
>"known" until run-time, can it be in another "unit" or for that matter
>a "dll"?

Hi Paul,

What is important here is that a method is treated as a typed
variable.

A buttons OnClick event is a TNotifyEvent.  It is defined as
procedure(sender:TObject) of object;

The 'of object' defines it as a method, and so it is not assignment
compatable with a normal procedure.  You must assign it to a method of
an object, but that can be any method of any object (as long as the
method is of the same type).

If you want to store a reference to an OnClick method you can use
this:

TForm1 = class(TForm)
  Button1: TButton;
private
  StoredOnClick : TNotifyEvent;
  procedure ButtonClick1(Sender: TObject);
  procedure ButtonClick2(Sender: TObject);
  procedure Swap;
end;

procedure TForm1.Swap;
begin;
StoredOnClick := button1.OnClick;
if button1.OnClick = ButtonClick1
  then button1.OnClick := ButtonClick2
  else button1.OnClick := ButtonClick1;
end;

not a great example, but it shown how events can be assigned, and how
they can be stored for later use (StoredOnClick).

Eamonn Mulvihill
Consultancy and programing services
-----------------------------------
Update Computer Services
Kent, England
u...@cableinet.co.uk
http://wkweb5.cableinet.co.uk/ucs/index.htm

Other Threads