1

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.
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Gabriel
  • 20,797
  • 27
  • 159
  • 293
  • 2
    It is a windows message with low priority, [`WM_TIMER`](https://learn.microsoft.com/en-us/windows/desktop/winmsg/wm-timer). See [using timers.](https://learn.microsoft.com/en-us/windows/desktop/winmsg/using-timers) It is not necessarily useful for exact time measurement. – nil Sep 26 '18 at 11:33
  • Why was the question down-voted? Itsn't valid/relevant? – Gabriel Sep 26 '18 at 13:02
  • Completely speculating but the downvote may have something got to do with what is asked and what is accepted. They seem to be totally unrelated, which may advise you have asked the wrong question. – Sertac Akyuz Sep 26 '18 at 13:18
  • @SertacAkyuz - 1. The downvote was cast immediately after I posted the question. so it is not related to the accepted answer. 2. Indeed the answer provided by Keith does not answer my specific questions. However, it does shine some light into the problem. And since it is the only (good) answer.... :) – Gabriel Sep 26 '18 at 13:51
  • @Rigel - Ok, thanks for explaining. I tried to answer your questions. – Sertac Akyuz Sep 26 '18 at 15:19
  • 1
    _"The documentations says that SetTimer requires Win2000 minimum. How was TTimer implemented in Win98?"_. `SetTimer` existed already on Windows 98/95 and even on Windows 3. Microsoft simply discarded any reference to Windows versions older than Windows 2000 in their documentation. – Jabberwocky Sep 27 '18 at 06:55

2 Answers2

7

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.

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
4

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.

Keith Miller
  • 1,718
  • 1
  • 13
  • 22
  • The WM_TIMER documentation confirms that WM_TIMER is a low priority message but it does not tell if ONLY one message is posted or not. – Gabriel Sep 26 '18 at 12:34
  • @Rigel I read the additional answer Keith linked and re-read the documentation and the part "The message is posted by the GetMessage or PeekMessage function." seems to indicate that Keith is right. – nil Sep 26 '18 at 12:36
  • ok. then Keith's answer is accepted. +1 and thank you both. I am reading the 3 sources of documentation you provided right now. – Gabriel Sep 26 '18 at 12:37
  • None of the 3 points asked seems to be addressed. Additionally seems to disagree with a claim that's never made. I mean the question does not claim or mention that the message is queued, It only tells that the message is processed by the message loop, which is correct. However being accepted, I think I somehow completely lost it. – Sertac Akyuz Sep 26 '18 at 13:15
  • @SertacAkyuz - I will DEFINITIVELY accept a better answer is one is posted :) – Gabriel Sep 26 '18 at 13:48
  • *"So there can never be more than one WM_TIMER message at a time in the queue"* - Combining `PeekMessage` with `PM_NOREMOVE` makes for some interesting changes to that statement (see [Even though mouse-move, paint, and timer messages are generated on demand, it’s still possible for one to end up in your queue](https://blogs.msdn.microsoft.com/oldnewthing/20130523-00/?p=4273)). – IInspectable Sep 27 '18 at 11:52