Alternative Sleep Methods
Post date: Mar 9, 2010 11:53:39 AM
It is possible for emulators to skip over sleep commands called using the Sleep API. Therefore, alternative methods prove useful in ensuring that your commands are not skipped; for application stability as well as security.
The advantages and disadvantages of each method are discussed.
1. Delay.
procedure Delay(dwMilliseconds: Longint);
var
iStart, iStop: DWORD;
begin
iStart := GetTickCount;
repeat
iStop := GetTickCount;
Application.ProcessMessages;
Sleep(1); // addition from Christian Scheffler to avoid high CPU last
until (iStop - iStart) >= dwMilliseconds;
end;
2. Delay: with API.
procedure Delay(msecs: Longint);
var
targettime: Longint;
Msg: TMsg;
begin
targettime := GetTickCount + msecs;
while targettime > GetTickCount do
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
if Msg.message = WM_QUIT then
begin
PostQuitMessage(Msg.wParam);
Break;
end;
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
{
Note:
The elapsed time is stored as a DWORD value.
Therefore, the time will wrap around to zero if the system is
run continuously for 49.7 days.
}
3. Sleep - suspends the execution of the current thread for a specified interval.
Sleep(dwMilliseconds: Word);
4. Combined Delay
Including the Sleep in the loop prevents the app from hogging 100% of the CPU for doing practically nothing but running around the loop.
procedure PauseFunc(delay: DWORD);
var
lTicks: DWORD;
begin
lTicks := GetTickCount + delay;
repeat
Sleep(100);
Application.ProcessMessages;
until (lTicks <= GetTickCount) or Application.Terminated;
end;
5. Delay - more resource sparing.
procedure Delay(Milliseconds: Integer);
{by Hagen Reddmann}
var
Tick: DWORD;
Event: THandle;
begin
Event := CreateEvent(nil, False, False, nil);
try
Tick := GetTickCount + DWORD(Milliseconds);
while (Milliseconds > 0) and
(MsgWaitForMultipleObjects(1, Event, False, Milliseconds,
QS_ALLINPUT) <> WAIT_TIMEOUT) do
begin
Application.ProcessMessages;
Milliseconds := Tick - GetTickCount;
end;
finally
CloseHandle(Event);
end;
end;