Search code examples
delphieventsdelphi-7

I want to create or change an event on a form, dynamically, how can i do that?


i'm trying to write a taskbar for my program, and i need to add one line of code in 2 events, OnClose and OnActivate, but my program has over 100 forms, so i'd like to do it dynamically. Is there an way to do it?

The language is Delphi 7.


Solution

  • As TLama and David Hefferman say, inheritance is right way to do it, but sometimes pragmatism wins out over the right way. So here is a horrible Kludge that will do the job.

    unit Unit1;
    
    interface
    
    uses
      VCL.Forms,
      System.Classes,
      System.Generics.Collections;
    
    type
      TKludge = class
      private
        fForm: TForm;
        fOnClose: TCloseEvent;
        fOnActivate: TNotifyEvent;
        procedure fNewOnActivate( Sender : TObject );
        procedure fNewOnClose( Sender : TObject; var Action : TCloseAction );
      public
        property Form : TForm
                 read fForm;
        property OnClose : TCloseEvent
                 read fOnClose;
        property OnActivate : TNotifyEvent
                 read fOnActivate;
        constructor Create( pForm : TForm );
    
      end;
    
      TKludges = class( TObjectList<TKludge> )
      private
        fApplication: TApplication;
        procedure SetApplication(const Value: TApplication);
      public
        property Application : TApplication
                 read fApplication
                 write SetApplication;
      end;
    
    
    implementation
    
    { TKludge }
    
    constructor TKludge.Create(pForm: TForm);
    begin
      fForm := pForm;
      fOnClose := pForm.OnClose;
      pForm.OnClose := fNewOnClose;
      fOnActivate := pForm.OnActivate;
      pForm.OnActivate := fOnActivate;
    end;
    
    procedure TKludge.fNewOnActivate(Sender: TObject);
    begin
      if assigned( fOnActivate ) then fOnActivate( Sender );
      // my extra line
    end;
    
    procedure TKludge.fNewOnClose(Sender: TObject; var Action: TCloseAction);
    begin
      if assigned fOnClose then fOnClose( Sender, Action );
      // my extra line
    end;
    
    { TKludges }
    
    procedure TKludges.SetApplication(const Value: TApplication);
    var
      i: Integer;
    begin
      fApplication := Value;
      for i := 0 to fApplication.ComponentCount do
      begin
        if fApplication.Components[ i ] is TForm then
        begin
          Add( TKludge.Create( fApplication.Components[ i ] as TForm ));
        end;
      end;
    end;
    
    end.
    

    Create an instance of the TKludges class and pass the Application to it. For every form that it finds it will replace the events with new ones that call the original if it exists and put your extra lines in (just comments at the minute).

    What makes it particularly horrible is the EVERY form will be affected, including ones you might not expect. But if you are sure...

    Use at your own risk!