| 
			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.
			 |