The violation occurs at the line "Suspended" in the callback. The timer component is the SVATimer.pas that I've used for years with good, accurate results. It does still run under Rio, but not Alexandria.
procedure MMTimerCallBack(TimerID, Msg: Uint; dwUser, dw1, dw2: DWORD); stdcall;
begin
with TSVATimerThread(dwUser) do
if Suspended then begin
TimeKillEvent(FTimerID);
FTimerID:= 0
end
else
Synchronize(FOwner.DoTimerProc)
end;
procedure TSVATimerThread.Execute;
begin
repeat
FTimerID:= TimeSetEvent(FInterval, 0, @MMTimerCallBack, cardinal(Self), TIME_PERIODIC);
if FTimerID <> 0 then
WaitForSingleObject(FEvent, INFINITE);
if FTimerID <> 0 then
TimeKillEvent(FTimerID)
until Terminated
end;
A pointer is a 32-bit value in a 32-bit build, and a 64-bit value in a 64-bit build. However, you are passing around your Self
pointer as a 32-bit value regardless of the build type, so it gets truncated in a 64-bit build.
You need to fix your declaration of MMTimerCallBack()
and the call to TimeSetEvent()
, per the documentation, so that you are passing the pointer correctly in both build types, eg:
procedure MMTimerCallBack(TimerID, Msg: UINT; dwUser, dw1, dw2: DWORD_PTR); stdcall;
begin
...
end;
procedure TSVATimerThread.Execute;
begin
...
FTimerID := TimeSetEvent(..., @MMTimerCallBack, DWORD_PTR(Self), ...);
...
end;