Author: Jonas Bilinkevicius
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:
1 unit uNilEvent;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 StdCtrls;
8
9 type
10 TForm1 = class(TForm)
11 Button1: TButton;
12 procedure Button1Click(Sender: TObject);
13 private
14 {Private declarations}
15 public
16 {Public declarations}
17 end;
18
19 var
20 Form1: TForm1;
21
22 implementation
23
24 {$R *.DFM}
25
26 uses
27 TypInfo;
28
29 procedure NilEvents(Instance: TObject);
30 var
31 TypeInfo: PTypeInfo;
32 I, Count: Integer;
33 PropList: PPropList;
34 PropInfo: PPropInfo;
35 Method: TMethod;
36 begin
37 TypeInfo := Instance.ClassInfo;
38 Method.Code := nil;
39 Method.Data := nil;
40 Count := GetPropList(TypeInfo, [tkMethod], nil);
41 GetMem(PropList, Count * SizeOf(Pointer));
42 try
43 GetPropList(TypeInfo, [tkMethod], PropList);
44 for I := 0 to Count - 1 do
45 begin
46 PropInfo := PropList^[I];
47 SetMethodProp(Instance, PropInfo, Method);
48 end;
49 finally
50 FreeMem(PropList);
51 end;
52 end;
53
54 procedure TForm1.Button1Click(Sender: TObject);
55 const
56 sText = 'The 2nd time you click Button1 the event will not fire';
57 begin
58 NilEvents(Button1);
59 ShowMessage(sText);
60 end;
61
62 end.
|