28 |
|
|
29 |
|
unit IBEvents; |
30 |
|
|
31 |
+ |
{$Mode Delphi} |
32 |
+ |
|
33 |
|
interface |
34 |
|
|
35 |
|
uses |
36 |
< |
SysUtils, Windows, Messages, Classes, Graphics, Controls, |
37 |
< |
Forms, Dialogs, DB, IBHeader, IBExternals, IB, IBDatabase; |
36 |
> |
{$IFDEF LINUX } |
37 |
> |
{$IFNDEF DESIGNTIME} cthreads,{$ENDIF}unix, |
38 |
> |
{$ELSE} |
39 |
> |
Windows, |
40 |
> |
{$ENDIF} Classes, Graphics, Controls, |
41 |
> |
Forms, Dialogs, IBHeader, IBExternals, IB, IBDatabase; |
42 |
|
|
43 |
|
const |
44 |
|
MaxEvents = 15; |
58 |
|
FOnEventAlert: TEventAlert; |
59 |
|
FQueued: Boolean; |
60 |
|
FRegistered: Boolean; |
55 |
– |
Buffer: TEventBuffer; |
61 |
|
Changing: Boolean; |
62 |
|
CS: TRTLCriticalSection; |
63 |
|
EventBuffer: PChar; |
117 |
|
|
118 |
|
{ TIBEvents } |
119 |
|
|
120 |
< |
procedure HandleEvent( param: integer); stdcall; |
120 |
> |
function HandleEvent( param: pointer): ptrint; |
121 |
|
begin |
122 |
|
{ don't let exceptions propogate out of thread } |
123 |
|
try |
125 |
|
except |
126 |
|
Application.HandleException( nil); |
127 |
|
end; |
128 |
+ |
EndThread; |
129 |
|
end; |
130 |
|
|
131 |
|
procedure IBEventCallback( ptr: pointer; length: short; updated: PChar); cdecl; |
126 |
– |
var |
127 |
– |
ThreadID: DWORD; |
132 |
|
begin |
133 |
|
{ Handle events asynchronously in second thread } |
134 |
|
EnterCriticalSection( TIBEvents( ptr).CS); |
135 |
|
TIBEvents( ptr).UpdateResultBuffer( length, updated); |
136 |
|
if TIBEvents( ptr).Queued then |
137 |
< |
CloseHandle( CreateThread( nil, 8192, @HandleEvent, ptr, 0, ThreadID)); |
137 |
> |
BeginThread( @HandleEvent,ptr); |
138 |
|
LeaveCriticalSection( TIBEvents( ptr).CS); |
139 |
|
end; |
140 |
|
|
144 |
|
FIBLoaded := False; |
145 |
|
CheckIBLoaded; |
146 |
|
FIBLoaded := True; |
147 |
< |
InitializeCriticalSection( CS); |
147 |
> |
InitCriticalSection( CS); |
148 |
|
FEvents := TStringList.Create; |
149 |
|
with TStringList( FEvents) do |
150 |
|
begin |
161 |
|
SetDatabase( nil); |
162 |
|
TStringList(FEvents).OnChange := nil; |
163 |
|
FEvents.Free; |
164 |
< |
DeleteCriticalSection( CS); |
164 |
> |
DoneCriticalSection( CS); |
165 |
|
end; |
166 |
|
inherited Destroy; |
167 |
|
end; |
292 |
|
procedure TIBEvents.RegisterEvents; |
293 |
|
var |
294 |
|
i: integer; |
295 |
< |
bufptr: pointer; |
292 |
< |
eventbufptr: pointer; |
293 |
< |
resultbufptr: pointer; |
294 |
< |
buflen: integer; |
295 |
> |
EventNames: array of PChar; |
296 |
|
begin |
297 |
|
ValidateDatabase( Database); |
298 |
|
if csDesigning in ComponentState then FRegistered := true |
299 |
|
else begin |
300 |
|
UnregisterEvents; |
301 |
|
if Events.Count = 0 then exit; |
302 |
+ |
setlength(EventNames,Events.Count); |
303 |
|
for i := 0 to Events.Count-1 do |
304 |
< |
StrPCopy( @Buffer[i][0], Events[i]); |
305 |
< |
i := Events.Count; |
306 |
< |
bufptr := @buffer[0]; |
307 |
< |
eventbufptr := @EventBuffer; |
306 |
< |
resultBufPtr := @ResultBuffer; |
307 |
< |
asm |
308 |
< |
mov ecx, dword ptr [i] |
309 |
< |
mov eax, dword ptr [bufptr] |
310 |
< |
@@1: |
311 |
< |
push eax |
312 |
< |
add eax, EventLength |
313 |
< |
loop @@1 |
314 |
< |
push dword ptr [i] |
315 |
< |
push dword ptr [resultBufPtr] |
316 |
< |
push dword ptr [eventBufPtr] |
317 |
< |
call [isc_event_block] |
318 |
< |
mov dword ptr [bufLen], eax |
319 |
< |
mov eax, dword ptr [i] |
320 |
< |
shl eax, 2 |
321 |
< |
add eax, 12 |
322 |
< |
add esp, eax |
323 |
< |
end; |
324 |
< |
EventBufferlen := Buflen; |
304 |
> |
EventNames[i] := PChar(Events[i]); |
305 |
> |
|
306 |
> |
EventBufferlen := isc_event_block(@EventBuffer,@ResultBuffer, |
307 |
> |
Events.Count,EventNames); |
308 |
|
FRegistered := true; |
309 |
|
QueueEvents; |
310 |
|
end; |