source: components/CoolTrayIcon/SimpleTimer.pas

Last change on this file was 1, checked in by maron, 16 years ago

3.1 verze, první revize

File size: 7.5 KB
Line 
1{*****************************************************************}
2{ SimpleTimer is a timer class. It has the same timer resolution }
3{ as TTimer, but it is more lightweight because it's derived from }
4{ TObject in stead of TComponent. Furthermore, the same handle is }
5{ shared between multiple instances of SimpleTimer. }
6{ This makes it ideal for developers who need a timer in their }
7{ own components or applications, but want to keep the resource }
8{ usage minimal. }
9{ }
10{ The unit is freeware. Feel free to use and improve it. }
11{ I would be pleased to hear what you think. }
12{ }
13{ Troels Jakobsen - delphiuser@get2net.dk }
14{ Copyright (c) 2002 }
15{*****************************************************************}
16
17unit SimpleTimer;
18
19{ Some methods have moved to the Classes unit in D6 and are thus deprecated.
20 Using the following compiler directives we handle that situation. }
21{$IFDEF VER140} {$DEFINE DELPHI_6} {$ENDIF}
22{$IFDEF VER150} {$DEFINE DELPHI_7} {$ENDIF}
23{$IFDEF DELPHI_6} {$DEFINE DELPHI_6_UP} {$ENDIF}
24{$IFDEF DELPHI_7} {$DEFINE DELPHI_6_UP} {$ENDIF}
25
26interface
27
28uses
29 Windows, Classes;
30
31type
32 TSimpleTimer = class(TObject)
33 private
34 FId: UINT;
35 FEnabled: Boolean;
36 FInterval: Cardinal;
37 FAutoDisable: Boolean;
38 FOnTimer: TNotifyEvent;
39 procedure SetEnabled(Value: Boolean);
40 procedure SetInterval(Value: Cardinal);
41 procedure SetOnTimer(Value: TNotifyEvent);
42 procedure Initialize(AInterval: Cardinal; AOnTimer: TNotifyEvent);
43 protected
44 function Start: Boolean;
45 function Stop(Disable: Boolean): Boolean;
46 public
47 constructor Create;
48 constructor CreateEx(AInterval: Cardinal; AOnTimer: TNotifyEvent);
49 destructor Destroy; override;
50 property Enabled: Boolean read FEnabled write SetEnabled;
51 property Interval: Cardinal read FInterval write SetInterval default 1000;
52 property AutoDisable: Boolean read FAutoDisable write FAutoDisable;
53 property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
54 end;
55
56function GetSimpleTimerCount: Cardinal;
57function GetSimpleTimerActiveCount: Cardinal;
58
59
60implementation
61
62uses
63 Messages{$IFNDEF DELPHI_6_UP}, Forms {$ENDIF};
64
65type
66 TSimpleTimerHandler = class(TObject)
67 private
68 RefCount: Cardinal;
69 ActiveCount: Cardinal;
70 FWindowHandle: HWND;
71 procedure WndProc(var Msg: TMessage);
72 public
73 constructor Create;
74 destructor Destroy; override;
75 procedure AddTimer;
76 procedure RemoveTimer;
77 end;
78
79var
80 SimpleTimerHandler: TSimpleTimerHandler = nil;
81
82
83function GetSimpleTimerCount: Cardinal;
84begin
85 if Assigned(SimpleTimerHandler) then
86 Result := SimpleTimerHandler.RefCount
87 else
88 Result := 0;
89end;
90
91
92function GetSimpleTimerActiveCount: Cardinal;
93begin
94 if Assigned(SimpleTimerHandler) then
95 Result := SimpleTimerHandler.ActiveCount
96 else
97 Result := 0;
98end;
99
100{--------------- TSimpleTimerHandler ------------------}
101
102constructor TSimpleTimerHandler.Create;
103begin
104 inherited Create;
105{$IFDEF DELPHI_6_UP}
106 FWindowHandle := Classes.AllocateHWnd(WndProc);
107{$ELSE}
108 FWindowHandle := AllocateHWnd(WndProc);
109{$ENDIF}
110end;
111
112
113destructor TSimpleTimerHandler.Destroy;
114begin
115{$IFDEF DELPHI_6_UP}
116 Classes.DeallocateHWnd(FWindowHandle);
117{$ELSE}
118 DeallocateHWnd(FWindowHandle);
119{$ENDIF}
120 inherited Destroy;
121end;
122
123
124procedure TSimpleTimerHandler.AddTimer;
125begin
126 Inc(RefCount);
127end;
128
129
130procedure TSimpleTimerHandler.RemoveTimer;
131begin
132 if RefCount > 0 then
133 Dec(RefCount);
134end;
135
136
137procedure TSimpleTimerHandler.WndProc(var Msg: TMessage);
138var
139 Timer: TSimpleTimer;
140begin
141 if Msg.Msg = WM_TIMER then
142 begin
143{$WARNINGS OFF}
144 Timer := TSimpleTimer(Msg.wParam);
145{$WARNINGS ON}
146 if Timer.FAutoDisable then
147 Timer.Stop(True);
148 // Call OnTimer event method if assigned
149 if Assigned(Timer.FOnTimer) then
150 Timer.FOnTimer(Timer);
151 end
152 else
153 Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam, Msg.lParam);
154end;
155
156{---------------- Container management ----------------}
157
158procedure AddTimer;
159begin
160 if not Assigned(SimpleTimerHandler) then
161 // Create new handler
162 SimpleTimerHandler := TSimpleTimerHandler.Create;
163 SimpleTimerHandler.AddTimer;
164end;
165
166
167procedure RemoveTimer;
168begin
169 if Assigned(SimpleTimerHandler) then
170 begin
171 SimpleTimerHandler.RemoveTimer;
172 if SimpleTimerHandler.RefCount = 0 then
173 begin
174 // Destroy handler
175 SimpleTimerHandler.Free;
176 SimpleTimerHandler := nil;
177 end;
178 end;
179end;
180
181{------------------ Callback method -------------------}
182{
183procedure TimerProc(hWnd: HWND; uMsg: UINT; idEvent: UINT; dwTime: DWORD); stdcall;
184var
185 Timer: TSimpleTimer;
186begin
187// if uMsg = WM_TIMER then // It's always WM_TIMER
188 begin
189 try
190 Timer := TSimpleTimer(idEvent);
191 if Assigned(Timer.FCallBackProc) then
192 Timer.FCallBackProc(Timer.FOwner);
193 except
194 // ???
195 end;
196 end;
197end;
198}
199{------------------- TSimpleTimer ---------------------}
200
201constructor TSimpleTimer.Create;
202begin
203 inherited Create;
204 Initialize(1000, nil);
205end;
206
207
208constructor TSimpleTimer.CreateEx(AInterval: Cardinal; AOnTimer: TNotifyEvent);
209begin
210 inherited Create;
211 Initialize(AInterval, AOnTimer);
212end;
213
214
215destructor TSimpleTimer.Destroy;
216begin
217 if FEnabled then
218 Stop(True);
219 RemoveTimer; // Container management
220 inherited Destroy;
221end;
222
223
224procedure TSimpleTimer.Initialize(AInterval: Cardinal; AOnTimer: TNotifyEvent);
225begin
226{$WARNINGS OFF}
227 FId := UINT(Self); // Use Self as id in call to SetTimer and callback method
228{$WARNINGS ON}
229 FAutoDisable := False;
230 FEnabled := False;
231 FInterval := AInterval;
232 SetOnTimer(AOnTimer);
233 AddTimer; // Container management
234end;
235
236
237procedure TSimpleTimer.SetEnabled(Value: Boolean);
238begin
239 if Value then
240 Start
241 else
242 Stop(True);
243end;
244
245
246procedure TSimpleTimer.SetInterval(Value: Cardinal);
247begin
248 if Value <> FInterval then
249 begin
250 FInterval := Value;
251 if FEnabled then
252 if FInterval <> 0 then
253 Start
254 else
255 Stop(False);
256 end;
257end;
258
259
260procedure TSimpleTimer.SetOnTimer(Value: TNotifyEvent);
261begin
262 FOnTimer := Value;
263 if (not Assigned(Value)) and (FEnabled) then
264 Stop(False);
265end;
266
267
268function TSimpleTimer.Start: Boolean;
269begin
270 if FInterval = 0 then
271 begin
272 Result := False;
273 Exit;
274 end;
275 if FEnabled then
276 Stop(True);
277// Result := (SetTimer(SimpleTimerHandler.FWindowHandle, FId, FInterval, @TimerProc) <> 0);
278 Result := (SetTimer(SimpleTimerHandler.FWindowHandle, FId, FInterval, nil) <> 0);
279 if Result then
280 begin
281 FEnabled := True;
282 Inc(SimpleTimerHandler.ActiveCount);
283 end
284{ else
285 raise EOutOfResources.Create(SNoTimers); }
286end;
287
288
289function TSimpleTimer.Stop(Disable: Boolean): Boolean;
290begin
291 if Disable then
292 FEnabled := False;
293 Result := KillTimer(SimpleTimerHandler.FWindowHandle, FId);
294 if Result and (SimpleTimerHandler.ActiveCount > 0) then
295 Dec(SimpleTimerHandler.ActiveCount);
296end;
297
298
299initialization
300
301finalization
302 if Assigned(SimpleTimerHandler) then
303 begin
304 SimpleTimerHandler.Free;
305 SimpleTimerHandler := nil;
306 end;
307
308end.
309
Note: See TracBrowser for help on using the repository browser.