简体   繁体   中英

How TTimer actually works internally?

A TTimer with the interval set to 1 sec sends a message every 1 second. This message is processed in application's message loop, which results in the OnTimer event being triggered.
If the application is busy and doesn't have time to process the message loop, the OnTimer event is skipped.

I knwo that TTimer uses internally SetTimer .

My questions are:

  1. Does TTimer use an internal/separate thread (via SetTimer)?
  2. How come that the form that holds the timer (and its OnTimer even) can still do stuff if a modal MessageDlg is "blocking" the form? (see code below)
  3. The documentations says that SetTimer requires Win2000 minimum. How was TTimer implemented in Win98?

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 Caption = i;
 i++;
 MessageDlg(stuff);      <----- we "block" application here but form's caption is still updated.
}

If the application is busy and doesn't have time to process the message loop, the OnTimer event is skipped.

That is effectively correct. This and this blog posts on MSDN give some internal implementation details, in particular they mention that an expiring timer causes the QS_TIMER flag of the message queue's state to be set. No further time lapse will cause the queue state flag to be even more set. When this flag is set and [Peek|Get]Message cannot pick any higher priority message, a timer message is generated.

Although timer messages do not pile up in the queue, it is possible to have the timer fire again while a previous event handler is executing. This is possible when the code in the handler takes longer to execute than the timer interval and re-entrancy is allowed. If the timer handler causes the application to process queued messages, any pending queue state flag may be cleared and the message posted again, which may cause the timer to fire before the handler finishes executing.

Does TTimer use an internal/separate thread (via SetTimer)?

No. A utility window is created in the main thread which will receive the timer messages. Upon receiving a timer message this window calls the event handler if one is assigned.

How come that the form that holds the timer (and its OnTimer even) can still do stuff if a modal MessageDlg is "blocking" the form?

The modal loop continues processing the queue, it calls HandleMessage of the Application in a loop which calls ProcessMessage . Hence timer messages are still processed.

That is a potential cause for re-entrancy mentioned above. You may use a flag or disable/enable the timer to prevent that. Or factor out any message processing in the handler altogether.

The documentations says that SetTimer requires Win2000 minimum. How was TTimer implemented in Win98

Same. Documentation keeps changing, occasionally MSDN drops unsupported OS versions from minimum requirements - rather inconsistently. My XE2 API documentation states:

Minimum operating systems Windows 95, Windows NT 3.1

for the WM_TIMER message.

WM_TIMER messages are never placed in the message queue. They are generated when the queue is empty and a flag indicating that the timer has expired is set. So there can never be more than one WM_TIMER message at a time in the queue and if you application is too busy to process the queue you don't get lots of WM_TIMER messages waiting to be processed.

WM_PAINT messages work the same way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM