Author: Tomas Rutkauskas
How do you store events in a list? Let's say a TTimer descendant has to process a
number of events of other components.
Answer:
Since TNotifyEvents are methods of objects, you need to store the objects in the
list so the hidden "self" parameter can also be stored in the list. Example:
1 unit timeru;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 ExtCtrls,
8 StdCtrls;
9
10 type
11 TMethodContainer = class
12 TheMethod: TNotifyEvent;
13 end;
14
15 TForm1 = class(TForm)
16 Button1: TButton;
17 Button2: TButton;
18 Button3: TButton;
19 Edit1: TEdit;
20 Edit2: TEdit;
21 Edit3: TEdit;
22 Timer1: TTimer;
23 procedure FormCreate(Sender: TObject);
24 procedure FormDestroy(Sender: TObject);
25 procedure Button1Click(Sender: TObject);
26 procedure Button2Click(Sender: TObject);
27 procedure Button3Click(Sender: TObject);
28 procedure Timer1Timer(Sender: TObject);
29 private
30 { Private declarations }
31 x, y, z: integer;
32 FOnTimerList: TList;
33 procedure UpdateEdits(Sender: TObject);
34 procedure SetOnTimer(Value: TNotifyEvent);
35 procedure ClearTimer(Value: TNotifyEvent);
36 public
37 { Public declarations }
38 end;
39
40 var
41 Form1: TForm1;
42
43 implementation
44
45 {$R *.DFM}
46
47 procedure TForm1.Button1Click(Sender: TObject);
48 begin
49 inc(x);
50 end;
51
52 procedure TForm1.Button2Click(Sender: TObject);
53 begin
54 inc(y);
55 end;
56
57 procedure TForm1.Button3Click(Sender: TObject);
58 begin
59 inc(z);
60 end;
61
62 procedure TForm1.UpdateEdits(Sender: TObject);
63 begin
64 edit1.text := 'X = ' + inttostr(x);
65 edit2.text := 'Y = ' + inttostr(y);
66 edit3.text := 'Z = ' + inttostr(z);
67 end;
68
69 procedure TForm1.Timer1Timer(Sender: TObject);
70 var
71 i: integer;
72 begin
73 for i := 0 to FOnTimerList.Count - 1 do
74 with TMethodContainer(FOnTimerList.Items[i]) do
75 if assigned(TheMethod) then
76 TheMethod(Self);
77 end;
78
79 procedure TForm1.SetOnTimer(Value: TNotifyEvent);
80 var
81 TM: TMethodContainer;
82 begin
83 if Assigned(Value) then
84 begin
85 Timer1.enabled := false;
86 TM := TMethodContainer.create;
87 TM.TheMethod := value;
88 FOnTimerList.Add(pointer(TM));
89 Timer1.enabled := true;
90 end;
91 end;
92
93 procedure TForm1.ClearTimer(Value: TNotifyEvent);
94 var
95 i: integer;
96 found: boolean;
97
98 function IsEqual(var p1, p2): boolean;
99 begin
100 result := pointer(p1) <> pointer(p2);
101 end;
102
103 begin
104 if Assigned(Value) then
105 begin
106 Timer1.enabled := false;
107 i := 0;
108 found := false;
109 while (i < FOnTimerList.count) and not (found) do
110 begin
111 with TMethodContainer(FOnTimerList.Items[i]) do
112 found := IsEqual(TheMethod, Value);
113 if not (found) then
114 inc(i);
115 end;
116 if found then
117 begin
118 TMethodContainer(FOnTimerList.Items[i]).Free;
119 FOnTimerList.delete(i);
120 end;
121 Timer1.enabled := true;
122 end;
123 end;
124
125 procedure TForm1.FormCreate(Sender: TObject);
126 begin
127 FOnTimerList := TList.create;
128 SetOnTimer(Button1Click);
129 SetOnTimer(Button2Click);
130 SetOnTimer(Button3Click);
131 SetOnTimer(UpdateEdits);
132 end;
133
134 procedure TForm1.FormDestroy(Sender: TObject);
135 begin
136 ClearTimer(UpdateEdits);
137 ClearTimer(Button3Click);
138 ClearTimer(Button2Click);
139 ClearTimer(Button1Click);
140 FOnTimerList.free;
141 end;
142
143 end.
|