[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2121
  • Last Modified:

Win32 Timers

I am programming a DirectX game in Delphi 2.0, and I want to have a timer fire off messages about 50 times a second so I can update the display and game variables. I tried the TTimer component that comes with Delphi, but the display kept "shaking" and I don't like this. Is it possible that I can utilize the timers in the Windows API? If so, how can I do this? Say I want Form1.OnUpdate to recieve the messages. How can I specify this in the Win32 SetTimer() function?
0
mmarvi
Asked:
mmarvi
  • 2
1 Solution
 
Answers2000Commented:
The WinAPI SetTimer functions uses a low precision clock.  Tick 18.2 per sec.  Too slow
0
 
BoRiSCommented:
mmarvi

Here is how the SetTimer API is called in delphi...

SetTimer(Form1.Handle, WM_TIMER, 50, nil);

Later
BoRiS


0
 
interCommented:
Here is the implementation part of correctly setting a high resolution multimedia timer, note that you can not acquire higher than your system reports, I think the code is self explanatory, anyway just ask if you stuck -I have already test the code-
regards, igor

implementation

uses
  mmsystem;

const
  TARGET_RESOLUTION = 1;         // 1-millisecond target resolution
var
  wTimerRes : UINT; //this is a global variable where we read the min timer period
  wTimerID : UINT; //id of our timer if succesfull

function Min(x,y : integer):integer;
begin
  Result := y;
  if x<y then Result := x;
end;

function Max(x,y : integer):integer;
begin
  Result := y;
  if x>y then Result := x;
end;

//obtain timer capabilities
function CheckTimerCaps:boolean;
var
 tc : TTIMECAPS;
begin
  if (timeGetDevCaps(@tc, sizeof(TTIMECAPS)) <> TIMERR_NOERROR) then
    Result := false
  else
  begin
    wTimerRes := min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
    timeBeginPeriod(wTimerRes);
    Result := true;
  end;
end;

//this is the core called by windows
procedure TimerCallback(TimerID , msg : UINT;
      dwUser, dw1, dw2 : DWORD); stdcall;
begin
  //************ DO WHAT YOU WANT HERE **************************
end;

// setup timer event and callback
// returns false if failed
// just give the number of miliseconds you want
function SetTimerCallback(msInterval : UINT):boolean;  // event interval
begin
    wTimerID := timeSetEvent(
        msInterval,                    // delay
        wTimerRes,                     // resolution (global variable)
        TimerCallback,               // callback function
        0,                  // user data
        TIME_PERIODIC );                // single timer event

    Result := wTimerID <> 0;
end;

procedure DestroyTimer;
begin
  if(wTimerID <> 0) then// is timer event pending?
  begin
     timeKillEvent(wTimerID);  // cancel the event
     wTimerID := 0;
  end;
end;


// TRY TO START TIMER with 10 msec
procedure TForm1.Button1Click(Sender: TObject);
begin
  if CheckTimerCaps then
    if SetTimerCallback(10) then
    begin
      ShowMessage('Timer Succesful : '+IntToStr(wTimerRes));
    end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  DestroyTimer;
end;

//DELETE TIMER
procedure TForm1.Button2Click(Sender: TObject);
begin
  DestroyTimer;
end;

end.  //unit
0
 
interCommented:
It generates periodic event as you want, but I missed a wrong comment there (I have addaped it before msdn)
regards, igor
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now