Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Timer code


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Feb 27, 2017 12:12 PM Last Post By: Remy Lebeau (Te...
Fred Smith

Posts: 81
Registered: 12/4/15
Timer code  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 27, 2017 2:46 AM
Hi,
Can this code be improved at all:
procedure MyTimer(hWnd: HWND; uMsg: Integer; idEvent: Integer; dwTime:   Integer); stdcall;
begin
  //writeln('Timer Event');
end;


procedure MyClass.Loop(bwait: boolean);
var
s: TDateTime;
id: uint;
begin
  try
    id := SetTimer(0, 1, 1000, @MyTimer);
    s := Now;
    while bwait do
    begin
      sleep(30);
      Application.ProcessMessages;
      if bwait = false then // Event fired, all good=> exit
      begin
        KillTimer(0, id);
        break;
      end;
 
      if Now - s > EncodeTime(0, 0, 1000, 0) then // Timed out=> exit
      begin
        KillTimer(0, id);
        break;  
      end;
    end;
 
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end;

Thank you.
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Timer code  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 27, 2017 10:46 AM   in response to: Fred Smith in response to: Fred Smith
Fred Smith wrote:

Hi,
Can this code be improved at all:

Easily, since it does not work at all the way you have written it.

procedure MyTimer(hWnd: HWND; uMsg: Integer; idEvent: Integer;
dwTime:   Integer); stdcall; begin
  //writeln('Timer Event');
end;


{code}
procedure MyClass.Loop(bwait: boolean);

You are passing bwait as a value parameter, so the input value the loop
sees will never change, even if you set the variable you pass to Loop
inside your timer procedure. You need to pass it as a Var parameter.

var
s: TDateTime;
id: uint;
begin
try
id := SetTimer(0, 1, 1000, @MyTimer);
s := Now;
while bwait do
begin
sleep(30);
Application.ProcessMessages;
if bwait = false then // Event fired, all good=> exit
begin
KillTimer(0, id);
break;
end;

if Now - s > EncodeTime(0, 0, 1000, 0) then // Timed out=> exit

You can calculate the target time for the timeout once, before the loop
starts, the calculation does not depend in any way on the loop itself.

s:= Now + EncodeTime(0, 0, 1000, 0);

The test then is a simple

if Now > s then
....

The whole construct stinks, however <g>. What are you trying to
accomplish here? And why are you using an API timer? You can as well
create a TTimer in code in the MyClass constructor and then use a
normal method of that class as event handler for the OnTimer event. No
need to mess with the API here at all.


--
Peter Below
TeamB

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Timer code  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 27, 2017 12:12 PM   in response to: Fred Smith in response to: Fred Smith
Fred wrote:

Can this code be improved at all:

Your same question on StackOverflow was answered earlier today:

http://stackoverflow.com/questions/42483300/

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02