Search code examples
delphieventsdelphi-6

Save and restore event handlers


My class contains dataset (TDataSet). Users of my class can assign event handlers for this dataset:

ds.FieldByName('ID').OnChange := @ID_OnChange;

Then I have to reopen dataset:

ds.Close;
ds.Open;

After this all event handlers are gone:

if Assigned(ds.FieldByName('ID').OnChange) //returns false

So, I need to save handlers and restore them after reopen. I use TStringList for it:

var
  EventHandlers: TStringList;
...
  //I do this for every event of every field
  if Assigned(ds.FieldByName('ID').OnChange) then
    EventHandlers.AddObject('ID', @ds.FieldByName('ID').OnChange);

The problem is how to restore handlers:

ds.FieldByName('ID').OnChange := TFieldNotifyEvent(ObjToInt(EventHandlers.Objects[0]));//Invalid typecast error

How can I assign stored address to event handler? Thanks.


Solution

  • If you really want to save the events, you can use TMethod Record:

    unit Unit6;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm6 = class(TForm)
        btn1: TButton;
        btn2: TButton;
        procedure btn1Click(Sender: TObject);
        procedure btn2Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        MTD : TMethod;
      end;
    
    var
      Form6: TForm6;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm6.btn1Click(Sender: TObject);
    begin
      ShowMessage('Hello World!');
    end;
    
    procedure TForm6.btn2Click(Sender: TObject);
    begin
      ShowMessage('I am copy cat!');
      MTD := TMethod(btn1.OnClick);
      btn2.OnClick := TNotifyEvent(MTD);
    end;
    
    end.
    

    The First Click on Btn2 will show "I am copy cat!" and The 2nd one will show Hello World.

    Edit : Improve assign event to MTD(TMethod). More simple and allow events from other objects.