How can I dynamically inject code into event handlers in Delphi?

前端 未结 5 2117
予麋鹿
予麋鹿 2020-12-17 00:31

For debugging / performance tests I would like to dynamically add logging code to all event handlers of components of a given type at run time.

For example, for all

5条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-17 01:27

    You can use the following scheme to rewire the datasets:

    type
      TDataSetEventWrapper = class
      private
        FDataSet: TDataSet;
        FOrgAfterOpen: TDataSetNotifyEvent;
        FOrgBeforeOpen: TDataSetNotifyEvent;
        procedure MyAfterOpen(DataSet: TDataSet);
        procedure MyBeforeOpen(DataSet: TDataSet);
      protected
        property DataSet: TDataSet read FDataSet;
      public
        constructor Create(ADataSet: TDataSet);
        destructor Destroy; override;
      end;
    
    constructor TDataSetEventWrapper.Create(ADataSet: TDataSet);
    begin
      Assert(ADataSet <> nil);
      inherited Create;
      FDataSet := ADataSet;
      FOrgAfterOpen := FDataSet.AfterOpen;
      FOrgBeforeOpen := FDataSet.BeforeOpen;
      FDataSet.AfterOpen := MyAfterOpen;
      FDataSet.BeforeOpen := MyBeforeOpen;
    end;
    
    destructor TDataSetEventWrapper.Destroy;
    begin
      FDataSet.AfterOpen := FOrgAfterOpen;
      FDataSet.BeforeOpen := FOrgBeforeOpen;
      inherited;
    end;
    
    procedure TDataSetEventWrapper.MyBeforeOpen(DataSet: TDataSet);
    begin
      if Assigned(FOrgBeforeOpen) then
        FOrgBeforeOpen(DataSet);
    end;
    
    procedure TDataSetEventWrapper.MyAfterOpen(DataSet: TDataSet);
    begin
      if Assigned(FOrgAfterOpen) then
        FOrgAfterOpen(DataSet);
    end;
    

    Inside MyAfterOpen and MyBeforeOpen you can bring in your code before, after or around the call to the original event handler.

    Collect the wrapper objects in a TObjectList with OwnsObjects := true and everything will revert to the original when you clear or free the objectlist.

    Caution: For this code to work the events have to be wired already when you create the wrappers and manually reassigning those events is forbidden.

提交回复
热议问题