-
Notifications
You must be signed in to change notification settings - Fork 0
/
JsTimers.pas
153 lines (123 loc) · 2.97 KB
/
JsTimers.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
unit JsTimers;
interface
uses
Windows, messages, Generics.Collections, Classes;
type
TOnTimerProc = reference to procedure;
function SetInterval(AProc: TOnTimerProc; ATimeout: Cardinal): cardinal;
function SetTimeout(AProc: TOnTimerProc; ATimeout: Cardinal): cardinal;
function ClearTimeout(id: cardinal): boolean;
function ClearInterval(id: cardinal): boolean;
procedure killAll;
type
TTimerwin = class
handle: HWND;
constructor create;
destructor free;
procedure handler(var Msg: TMessage);
end;
var
timerWin: hwnd;
w: TTimerwin;
t: NativeUInt;
TimerList: TDictionary<NativeUInt, TOnTimerProc>;
TimerListX: TDictionary<NativeUInt, TOnTimerProc>;
__kill: Boolean;
implementation
uses
JSNatives;
procedure killall;
var
Item: TPair<NativeUInt, TOnTimerProc>;
begin
__kill := true;
for Item in TimerList do
KillTimer(timerWin, Item.Key);
for Item in TimerListX do
KillTimer(timerWin, Item.Key);
timerlist.Clear;
TimerListX.Clear;
end;
procedure TimerProc(hwnd: hwnd; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD); stdcall;
var
Proc: TOnTimerProc;
begin
if TimerList.TryGetValue(idEvent, Proc) then
try
KillTimer(timerWin, idEvent);
if not __kill then
Proc();
finally
TimerList.Remove(idEvent);
end;
end;
procedure TimerProcX(hwnd: hwnd; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD); stdcall;
var
Proc: TOnTimerProc;
begin
if TimerListX.TryGetValue(idEvent, Proc) then
try
if not __kill then
Proc()
else
TimerListX.Remove(idEvent);
finally
end;
end;
function SetTimeout(AProc: TOnTimerProc; ATimeout: Cardinal): cardinal;
begin
if __kill then
exit;
Inc(t);
result := SetTimer(timerWin, t, ATimeout, @TimerProc);
TimerList.Add(result, AProc);
end;
function ClearTimeout(id: cardinal): boolean;
var
Proc: TOnTimerProc;
begin
if __kill then
exit;
Result := KillTimer(timerWin, id);
TimerList.Remove(id);
end;
function ClearInterval(id: cardinal): boolean;
var
Proc: TOnTimerProc;
begin
if __kill then
exit;
result := KillTimer(timerWin, id);
TimerListX.Remove(id);
end;
function SetInterval(AProc: TOnTimerProc; ATimeout: Cardinal): cardinal;
begin
if __kill then
exit;
Inc(t);
Result := SetTimer(timerWin, t, ATimeout, @TimerProcX);
TimerListX.Add(result, AProc);
end;
procedure ttimerwin.handler(var Msg: TMessage);
begin
Msg.Result := DefWindowProc(handle, Msg.Msg, Msg.wParam, Msg.lParam);
end;
constructor ttimerwin.create;
begin
handle := AllocateHWnd(handler);
end;
destructor ttimerwin.free;
begin
DeallocateHWnd(handle);
end;
initialization
t := 0;
w := ttimerwin.create;
timerwin := w.handle;
TimerList := TDictionary<NativeUInt, TOnTimerProc>.Create;
TimerListX := TDictionary<NativeUInt, TOnTimerProc>.Create;
finalization
TimerListX.Free;
TimerList.Free;
w.free;
end.