Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: Windows message handling (WM_TIMER)


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


Permlink Replies: 6 - Last Post: Nov 5, 2017 7:12 AM Last Post By: Marc Van den Br... Threads: [ Previous | Next ]
Goran Ekstrom

Posts: 136
Registered: 1/10/04
Windows message handling (WM_TIMER)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2017 12:15 PM
Hi,
does Windows check for "duplicate" messages in the kernel messaging functionality? My specific question is about the WM_TIMER message. Will the timer events accumulate in the message queue if unhandled or will windows skip the new WM_TIMER message if it finds unhandled WM_TIMER messages in the queue?

Regards
Goran

Edited by: Goran Ekstrom on Mar 10, 2017 1:30 PM
Remy Lebeau (Te...


Posts: 8,950
Registered: 12/23/01
Re: Windows message handling  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2017 1:07 PM   in response to: Goran Ekstrom in response to: Goran Ekstrom
Goran wrote:

does Windows check for "duplicate" messages in the kernel messaging
functionality?

For the most part, no. WM_PAINT is an exception to that, as multiple WM_PAINT
messages do get consolidated into a single WM_PAINT.

My specific question is about the WM_TIMER message. Will the timer events
accumulate in the message queue if unhandled or will windows skip the new
WM_TIMER message if it finds unhandled WM_TIMER messages in the queue?

Under normal circumstances, there will not be duplicates.

A timer-generated WM_TIMER is not a real message queued by the timer, it
is a synthesized message that is not queued until it is requested (WM_TIMER
is one of several sythesized messages generated by the message queue - others
include WM_PAINT, WM_QUIT, WM_MOUSEMOVE, etc). The message queue knows when
a timer has elapsed, and will queue a WM_TIMER message for that timer only
when the message queue does not have any other higher-priority messages to
return. Typically, the queued WM_TIMER message is then removed from the
queue immediately, thus it will not accumulate.

Your question is actually answered on Raymond Chen's MSDN blog:

If my WM_TIMER handler takes longer than the timer period, will my queue
fill up with WM_TIMER messages?
https://blogs.msdn.microsoft.com/oldnewthing/20141204-00/?p=43473

What happens to lost timer messages if I don’t process them fast enough?
https://blogs.msdn.microsoft.com/oldnewthing/20150928-00/?p=91501

Message filtering can complicate WM_TIMER handling, though:

Killing a window timer prevents the WM_TIMER message from being generated
for that timer, but it doesn’t retroactively remove ones that were already
generated
https://blogs.msdn.microsoft.com/oldnewthing/20141205-00/?p=43463

And a COM modal loop uses message filtering that ignores WM_TIMER:

Why is my message queue full of WM_TIMER messages?
https://blogs.msdn.microsoft.com/oldnewthing/20160624-00/?p=93745

--
Remy Lebeau (TeamB)
Goran Ekstrom

Posts: 136
Registered: 1/10/04
Re: Windows message handling  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2017 1:33 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks Remy.

This case relates to an earlier thread about not using TTimer in TThreads. Since I have a plethora of different timers in my app, all historically dependent on TTimer event handlers, I opted to implement the winapi SetTimer() functionality directly in my threads where I create a hidden window that receives the WM_TIMER messages. My problem is that if the thread does something that takes longer than the timer interval it seems that timer events are lost, i.e. when the thread eventually gets to handle the message queue there seems to not be the same amount of elapsed timer events in the queue so the app functionality timing screws up.

Edit:
As I understand this:
https://blogs.msdn.microsoft.com/oldnewthing/20141204-00/?p=43473

... there will only be a WM_TIMER message in the queue if the timer has elapsed and then only when I empty the message queue. Therefore my whole timing scheme gets screwed if the thread does not empty the message queue faster than the timer interval.

Edit 2:
If I place the SetTimer functionality in a dedicated (timer only) thread that uses GetMessage (blocking) to empty the queue, will that "guarantee" that no WM_TIMER events are missed? Rephrased, will the blocking GetMessage return "immediately" as the WM_TIMER event is flagged?

Regards
Goran

Remy Lebeau (Te...


Posts: 8,950
Registered: 12/23/01
Re: Windows message handling [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2017 2:07 PM   in response to: Goran Ekstrom in response to: Goran Ekstrom
Goran wrote:

This case relates to an earlier thread about not using TTimer in
TThreads.

Since TTimer is not thread-safe to begin with, you shouldn't be using it
in a TThread at all. There are better ways to handle timers in threads,
such as using a Waitable Timer, or a Multimedia Timer (which runs in its
own thread).

Since I have a plethora of different timers in my app, all historically
dependent on TTimer event handlers, I opted to implement the winapi
SetTimer() functionality directly in my threads where I create a hidden
window that receives the WM_TIMER messages.

You don't need an HWND to use SetTimer(), you can use a callback function
instead. Either way, you just need a message loop to trigger the timer handler
(message or callback), and that works fine in a thread without a window.

My problem is that if the thread does something that takes longer than
the timer interval it seems that timer events are lost, i.e. when the
thread eventually gets to handle the message queue there seems to
not be the same amount of elapsed timer events in the queue

Correct, and that is answered in the links I gave you.

so the app functionality timing screws up.

TTimer (and more generally, SetTimer()) is not a real-time timer to begin
with. Even if it did not lose events, the timing of the events is not guaranteed,
particularly since the message queue is involved. If your app is screwing
up simply because you are missing events, or the events are not that the
expected times, than your app probably isn't coded very well to begin with.
If timing is important, you might just be better off using a simple loop
instead.

As I understand this:
https://blogs.msdn.microsoft.com/oldnewthing/20141204-00/?p=43473
... there will only be a WM_TIMER message in the queue if the timer
has elapsed and then only when I empty the message queue.

Under normal conditions, yes.

Therefore my whole timing scheme gets screwed if the thread does not
empty the message queue faster than the timer interval.

If the thread is taking too long to process timer events, you might want
to think about moving the timer to a different thread, or jsst get rid of
the timer altogether.

If I place the SetTimer functionality in a dedicated (timer only)
thread that uses GetMessage (blocking) to empty the queue, will that
"guarantee" that no WM_TIMER events are missed?

Yes, provided that the timer thread does not try to actually process the
message before the next interval is due. If the processing is in a separate
thread, just make sure the dispatching of the timer event to that other thread
does not block the timer thread for more than the timer interval.

Rephrased, will the blocking GetMessage return "immediately" as the
WM_TIMER event is flagged?

Yes, if there are no other messages waiting (which is not likely in a dedicated
thread, except for system broadcasts).

--
Remy Lebeau (TeamB)
Goran Ekstrom

Posts: 136
Registered: 1/10/04
Re: Windows message handling [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 8, 2017 2:24 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Since TTimer is not thread-safe to begin with, you shouldn't be using it
in a TThread at all..

Yes, as we discussed in another thread recently.

TTimer (and more generally, SetTimer()) is not a real-time timer to begin
with.

That is my conclusion today and since my app requires real-time based timers I will have to choose another way.

... If your app is screwing
up simply because you are missing events, or the events are not that the
expected times, than your app probably isn't coded very well to begin with.

By "screwing up" I mean that my app timing timebase is not working properly which means the timers are not real or close to real time resulting in timeouts, timers etc. being wrong, not that the app crashes.

Rephrased, will the blocking GetMessage return "immediately" as the
WM_TIMER event is flagged?
Yes, if there are no other messages waiting (which is not likely in a dedicated
thread, except for system broadcasts).

Yes, that is a possible way but I am leaning towards a multimedia timer or as MSDN recommends, a CreateTimerQueueTimer.

Regards
Goran
Goran Ekstrom

Posts: 136
Registered: 1/10/04
Re: Windows message handling (WM_TIMER)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 4:28 AM   in response to: Goran Ekstrom in response to: Goran Ekstrom
So, CreateTimerQueue() with CreateTimerQueueTimer() and TMultiReadExclusiveWriteSynchronizer made a good real time timer time base so all seems well and TTimer is removed from all TThreads.

One question:
The OS timer uses a callback function, how does it work with OS callback functions and debugging? Are the callbacks halted when the execution is paused in the debugger?

Regards
Goran
Marc Van den Br...

Posts: 10
Registered: 6/16/07
Re: Windows message handling (WM_TIMER)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 5, 2017 7:12 AM   in response to: Goran Ekstrom in response to: Goran Ekstrom
Goran Ekstrom wrote:
Hi,
does Windows check for "duplicate" messages in the kernel messaging functionality? My specific question is about the WM_TIMER message. Will the timer events accumulate in the message queue if unhandled or will windows skip the new WM_TIMER message if it finds unhandled WM_TIMER messages in the queue?

Regards
Goran

Edited by: Goran Ekstrom on Mar 10, 2017 1:30 PM

all ya need to do is setting in a any win a message map calling WM_TIMER WM is Windows Message handler, since .NET they use this so WM_CLOSE looking to just the titles off applications closes the system. as a Timer don't exist only a timeout , if ya use win32 api WaiForSingleObject(HANDLE,<time in msec,or INFINITE) is far efficent
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02