[comp.windows.ms.programmer] Using a timer to "sleep"

goble@wolf.cs.washington.edu (Brian Goble) (11/20/90)

I have a Timer installed in my Win3 app and it gets called directly (ie, no
WM_TIMER msg gets sent to my application).  The timer gets called at approx.
1 second intervals.  In the timer callback function, I increment a global
variable "TimerCounter".

What I would like to do is use this TimerCounter value to be able to
do delays like when I display a message or something.  I tried something
like:

	TimerCounter = 0;
	while (TimerCounter < 5) { TimerCounter = TimerCounter; /* nothing */

but it just spins in the loop.  Does the timer callback function not
interrupt the current execution?  Is there a windows function or an MS C
function (like Turbo C's "sleep()") that will do a delay?

Thanx in advance for any help...

Brian Goble		| goble@wolf.cs.washington.edu

karel@prisma.cv.ruu.nl (Karel Zuiderveld) (11/21/90)

In <13796@june.cs.washington.edu> goble@wolf.cs.washington.edu (Brian Goble) writes:

>Is there a windows function or an MS C
>function (like Turbo C's "sleep()") that will do a delay?
>

Yes, there is a very easy way to do it. The function

DWORD GetTickCount()

returns the number of milliseconds that have elpased since the system 
was started. A windows sleep function can very easily be coded:

VOID FAR PASCAL wsleep(int iNrSeconds)
{
    DWORD lCountStop = GetTickCount() + 1000L * (DWORD) iNrSeconds;
    
    while (GetTickCount() < lCountStop);
}

Of course there is one but with this approach: all CPU power is spend
in that loop. 

The WM_TIMER approach should also work BTW.

Karel
-- 
Karel Zuiderveld                            E-mail: karel@cv.ruu.nl
3D Computer Vision - Room E.02.222          Tel:    (31-30) 506682/507772
Academisch Ziekenhuis Utrecht               Fax:    (31-30) 513399
Heidelberglaan 100, 3584 CX Utrecht, The Netherlands

arybicki@dhw68k.cts.com (Adam Rybicki) (11/21/90)

In article <13796@june.cs.washington.edu> goble@wolf.cs.washington.edu (Brian Goble) writes:
>I have a Timer installed in my Win3 app and it gets called directly (ie, no
>WM_TIMER msg gets sent to my application).  The timer gets called at approx.
>1 second intervals.  In the timer callback function, I increment a global
>variable "TimerCounter".
>
>What I would like to do is use this TimerCounter value to be able to
>do delays like when I display a message or something.  I tried something
>like:

First of all, you will not be able to retrieve any messages until you call
GetMessage () or PeekMessage ().  Once one of those retrieves the WM_TIMER message
from your application's queue, DispatchMessage () will call your TimerProc ()
(or whatever you called it) function.

Secondly, looping around has never been a good multitasking-friendly way to
kill time.

Why don't you try to do whatever you need to do after 5 seconds in the
TimerProc () function instead of in-line.


>
>Brian Goble		| goble@wolf.cs.washington.edu


Adam Rybicki

ed@odi.com (Ed Schwalenberg) (11/24/90)

In article <karel.659135309@prisma> karel@prisma.cv.ruu.nl (Karel Zuiderveld) writes:

  In <13796@june.cs.washington.edu> goble@wolf.cs.washington.edu (Brian Goble) writes:

  >Is there a windows function or an MS C
  >function (like Turbo C's "sleep()") that will do a delay?
  >

  VOID FAR PASCAL wsleep(int iNrSeconds)
  {
      DWORD lCountStop = GetTickCount() + 1000L * (DWORD) iNrSeconds;

      while (GetTickCount() < lCountStop);
  }

  Of course there is one but with this approach: all CPU power is spend
  in that loop. 

while (GetTickCount() < lCountStop) Yield();
lets other Windows processes run while you're sleeping.  Even better is
to integrate the sleepiness with your program's message loop; see the
documentation on PeekMessage.

davidds@microsoft.UUCP (David D'SOUZA) (11/26/90)

In article <13796@june.cs.washington.edu> goble@wolf.cs.washington.edu
(Brian Goble) writes:
>What I would like to do is use this TimerCounter value to be able to
>do delays like when I display a message or something.  I tried something
>like:
>
>	TimerCounter = 0;
>	while (TimerCounter < 5) { TimerCounter = TimerCounter; /* nothing */
>
>but it just spins in the loop.  Does the timer callback function not
>interrupt the current execution?  Is there a windows function or an MS C
>function (like Turbo C's "sleep()") that will do a delay?

This won't work as you found out...  Windows timers are synchronous
beasts, and in fact, can only be triggered when you are calling
GetMessage.  Another problem is Windows applications aren't
preemptively multitasked so you want to be careful about busy waiting
because you are starving other applications of processor time.

Here is a quick and dirty way to do a nice delay loop. Note, you  also
need to becareful about GetTickCount wrapping back to zero...  The
Yield()  gives time to other applications.  Note that if you are
running in REAL mode, when you Yield, your DS can move so be sure you
don't have any far pointers into your ds. (Check out LockSegment(-1) if
this is a problem.)


DWORD tickCount;
tickCount = GetTickCount();
while (ABSOLUTEVALUE(GetTickCount() - tickCount) < MYDELAYTIME)
       Yield();