Delphi Timer: Time before next event

2020-02-06 23:45发布

Is it possible to determine when a TTimer in Delphi will trigger? I know how to calculate this based upon the timer's last run and the timers interval. Unfortunately, the code I am working with has many states and the interval can change in many ways. I would prefer to not have to keep track of when the timer was last enabled and the interval changed, but instead directly access this information from the timer.

Scenario: A timer has a 2 minute interval, 30 seconds have elapsed since it was last enabled, how do I find out in code that in 90 seconds the timer event will trigger again?

Is it possible to get this information from the timer directly? Or perhaps the OS? The timer component must "know" when it will be triggered next. How does it know? Is this information I can access?

标签: delphi timer
2条回答
相关推荐>>
2楼-- · 2020-02-07 00:13

There's absolutely no way to query a Windows timer for information of this nature. You will simply have to keep track of this yourself.

I would do this by wrapping up the TTimer with composition and not inheritance. You can then be sure that you will capture all modifications to the timer state.

查看更多
再贱就再见
3楼-- · 2020-02-07 00:21

In this case I recommend you switch from a TTimer which uses Windows timers, to a thread based TTimer-style component. Then you can query the time until the next event.

Alternative; If you want a simple ugly hack, then change your Timer interval to 1 second instead of 120 seconds, and do a countdown yourself:

   const
     CounterPreset = 120;

   ...

   procedure TForm1.FormCreate(Sender:TObject);
   begin
      FCounter := CounterPreset;
      Timer1.Interval := 1000;
      Timer1.Enabled := true;
   end;

   procedure TForm1.Timer1Timer(Sender);
   begin
           Dec(FCounter);
           if (FCounter<=0) then
           begin
              DoRealTimerCodeHere;
              FCounter := CounterPreset;
           end;
   end;

   function  TForm1.TimeLeft:Integer;
   begin
         result := FCounter;
   end;

This will be inaccurate subject to the limitations of the WM_TIMER message, documented only vaguely at MSDN here. Real experience shows that WM_TIMER should only be used for things that don't need to happen at all, and should be used as a convenience, not as a hard-timing system.

查看更多
登录 后发表回答