2008. február 19., kedd

How to set all events of an object to NIL at runtime


Problem/Question/Abstract:

Is there a way to enumerate all of an objects events at runtime and set them to nil?

Answer:

You can use RTTI to accomplish your goal, but only for published, not public, events. Using RTTI is pretty complex, so I've written a working utility procedure for you which takes any object instance and assigns nil to its published events:

unit uNilEvent;

interface

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

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

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  TypInfo;

procedure NilEvents(Instance: TObject);
var
  TypeInfo: PTypeInfo;
  I, Count: Integer;
  PropList: PPropList;
  PropInfo: PPropInfo;
  Method: TMethod;
begin
  TypeInfo := Instance.ClassInfo;
  Method.Code := nil;
  Method.Data := nil;
  Count := GetPropList(TypeInfo, [tkMethod], nil);
  GetMem(PropList, Count * SizeOf(Pointer));
  try
    GetPropList(TypeInfo, [tkMethod], PropList);
    for I := 0 to Count - 1 do
    begin
      PropInfo := PropList^[I];
      SetMethodProp(Instance, PropInfo, Method);
    end;
  finally
    FreeMem(PropList);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  sText = 'The 2nd time you click Button1 the event will not fire';
begin
  NilEvents(Button1);
  ShowMessage(sText);
end;

end.

Nincsenek megjegyzések:

Megjegyzés küldése