Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
Bob Swart (aka Dr.Bob) - Medical Officer Delphi in a Nutshell
 Under The Hood #8 - Time to Sleep
See Also: Delphi Papers and Dr.Bob's Examines Columns

Sometimes, it would be nice to have the ability to put an application to sleep for a short (or longer) while, and be sure to wake up and continue afterwards. In DOS, we had this nice little Delay (or Sleep, depending on your background) function. But what about Delphi??

This time, we will create a delay/sleep function in an ObjectPascal unit that does not have a form. Of course, we could decide to use a TTimer for this problem, but it's not always practical to (dynamically if needed) create a TTimer and set up the response event, so let's go for the non-timer approach.
In order to ensure portablility of our solution, it's good to know that both Windows 3.x and Win32 (Win95/NT) support the GetTickCount API.
The GetTickCount API gives us the number of milliseconds since Windows was started. The accuracy of this API, however, is only 55 ms, as it is updated 18.2 times each second (just like the real mode system clock). Hence, we should use GetTickCount only for very rough measurements. But it's accurate enough to be used in a while loop that does nothing until the GetTickCount is the StartingTime + the amount of milliseconds we wanted to wait:

  StartTime := GetTickCount;
  while (GetTickCount < (StartTime + MilliSecondsToWait)) do
Also, as the result is stored in a LongInt, its value will overflow after about 49 days (although I've never found anyone who had been able to get Windows up and running that long to verify). Still, to prepare for the theoretical overflow, we need to include the check
  while (GetTickCount >= StartTime) ...
as well (and bail out if the GetTickCount has overflown and become 0 again - in which case we'll sleep less than anticipated, but at least we wake up, which is better than staying in a coma).
  program Hood8;
  uses
    WinProcs, Forms, WinCrt;

    procedure Sleep(MilliSecondsToWait: LongInt);
    var StartTime: LongInt;
    begin
      StartTime := GetTickCount;
      while (GetTickCount >= StartTime) and
            (GetTickCount < (StartTime + MilliSecondsToWait)) do
        Application.ProcessMessages
    end {Sleep};

  var i: Integer;
  begin
    writeln(GetTickCount);
    for i:=1 to 10 do
    begin
      Sleep(i * 1000);
      writeln(GetTickCount);
    end
  end.
Note that within the while-loop, we need to call Application.ProcessMessages, in order to make sure that the other programs on our machine will not be put asleep either (while our program is hogging the CPU in the while-do-nothing loop).

All in all, this is a tiny but powerful routine that can come in real handy at times. And yes, it will work with Delphi 2.x as well, although you might want to check out the Win32 API called "sleep" instead...


This webpage © 1996-2017 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.