Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

WM_TIMER prevents window from being displayed ???

141 views
Skip to first unread message

hpesata

unread,
Jul 4, 2008, 11:26:14 AM7/4/08
to
Hi !

I wrote an MFC app using VC++ .NET 2003.

our app uses multiple docking panes which are created dynamically be
selected menu-entries.
additonaly we have a function which starts a timer to update data
within the visible docking panes, this is also started via a menu-
entry.

If the timer is already running and we create another docking pane,
this pane doesnt become visible
until we stop the timer. this happens if the timer is using a period
like 10-50 ms. it works fine with higher periods like 300ms.

what can be the reason of this ? I tried to use InvalidateRect(0,
TRUE) and UpdateWindow() after creating the new pane but this didnt
help.

how can I achieve to make my new pane visible ?

any help with this would be greatly apreciated,
thanx in advance!

regards,
Hans

David Lowndes

unread,
Jul 4, 2008, 12:09:03 PM7/4/08
to
>If the timer is already running and we create another docking pane,
>this pane doesnt become visible
>until we stop the timer. this happens if the timer is using a period
>like 10-50 ms. it works fine with higher periods like 300ms.
>
>what can be the reason of this ?

Your application is never getting to process WM_PAINT messages because
WM_TIMER messages are treated as a higher priority.

>how can I achieve to make my new pane visible ?

As you've discovered - slow down your timers to something reasonable.

Dave

Joseph M. Newcomer

unread,
Jul 4, 2008, 12:36:38 PM7/4/08
to
Windows is not a real-time system. Keep repeating this until you understand it. This
means that trying to do things at very fine timer resolutions is intrinsically doomed
nearly all the time.

As already pointed out, you are swamping the thread queue with timer messages, which means
that the WM_PAINT never gets a chance.

You can sometimes get away with using the multimedia timers, just bear in mind that the
timer callback is always executed in a separate thread of control and consequently cannot
touch your windows. If you PostMessage at the same rate you are using now, you will see
the same phenomenon. You might want to see my essay on the use of I/O Completion Ports to
prevent message queue saturation and various umpleasant side effects (delayed user
interaction, failure to repaint).
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

David Ching

unread,
Jul 4, 2008, 2:52:38 PM7/4/08
to
"David Lowndes" <Dav...@example.invalid> wrote in message
news:3iis64102b7i5dsne...@4ax.com...

> Your application is never getting to process WM_PAINT messages because
> WM_TIMER messages are treated as a higher priority.
>

My experience is the opposite. I had a similar situation, where I created
some controls and needed them to paint before starting a lengthy operation
that tied up the primary UI thread. I tried to defer the lengthy operation
by doing a PostMessage(MY_WM_START_LENGTHY_PROCESS), hoping that before
OnMyStartLengthyProcess() was called, the UI would paint. But it didn't.

The workaround was to call SetTimer(0), and discovered to my happiness that
OnTimer() was called after the paint occurred. So in my OnTimer(), I
started the lengthy process, after the paint occurred. So this seems to
indicate WM_PAINT is higher priority than WM_TIMER.

-- David


David Lowndes

unread,
Jul 4, 2008, 3:40:05 PM7/4/08
to
>My experience is the opposite.
>...

>
>The workaround was to call SetTimer(0), and discovered to my happiness that
>OnTimer() was called after the paint occurred. So in my OnTimer(), I
>started the lengthy process, after the paint occurred. So this seems to
>indicate WM_PAINT is higher priority than WM_TIMER.

In fact the GetMessage documentation agrees with you:

"If no filter is specified, messages are processed in the following
order:

Sent messages
Posted messages
Input (hardware) messages and system internal events
Sent messages (again)
WM_PAINT messages
WM_TIMER messages
"

Perhaps the situation of the OP isn't quite so clear cut, but
nevertheless, expecting to handle WM_TIMER messages so frequently is
not going to be reliable or a good way of doing things.

Dave

David Ching

unread,
Jul 4, 2008, 4:27:00 PM7/4/08
to
"David Lowndes" <Dav...@example.invalid> wrote in message
news:ftus64lo0oiff1b0k...@4ax.com...

> In fact the GetMessage documentation agrees with you:
>
> "If no filter is specified, messages are processed in the following
> order:
>
> Sent messages
> Posted messages
> Input (hardware) messages and system internal events
> Sent messages (again)
> WM_PAINT messages
> WM_TIMER messages
> "

Thanks, I hadn't found concrete evidence of this priority, it's good to know
it's documented.


> Perhaps the situation of the OP isn't quite so clear cut, but
> nevertheless, expecting to handle WM_TIMER messages so frequently is
> not going to be reliable or a good way of doing things.
>

Not sure what is going on with him. Maybe he should kill and reset the
timer after he adds the panes. I did comment my code that I first had to
call SetTimer(0), and only after the first OnTimer() was called did I call
SetTimer(<original ms value>) to get normal timer messages after that.
Apparently the SetTimer(0) was important for the paint to occur at the right
time....

-- David

hpesata

unread,
Jul 5, 2008, 7:36:20 AM7/5/08
to
Hi Joe!

> Windows is not a real-time system.  Keep repeating this until you understand it.  This
> means that trying to do things at very fine timer resolutions is intrinsically doomed
> nearly all the time.
>
> As already pointed out, you are swamping the thread queue with timer messages, which means
> that the WM_PAINT never gets a chance.  
>
> You can sometimes get away with using the multimedia timers, just bear in mind that the
> timer callback is always executed in a separate thread of control and consequently cannot
> touch your windows.  If you PostMessage at the same rate you are using now, you will see
> the same phenomenon.  You might want to see my essay on the use of I/O Completion Ports to
> prevent message queue saturation and various umpleasant side effects (delayed user
> interaction, failure to repaint).

thanx a lot for Your reply!

I forgot to mention that we dont use WM_TIMER notifications, instead
we use a callback function.
so the message-queue shouldnt be filled up with WM_TIMER
notifications ?!
do I miss something here ?

I read Your essay and I have a few questions about it:

as far as I understand I should use Your the MsgWrapper::Post()
function
instead of the PostMessage() method to notify my gui-therad about
changes.
but You are using 1 for the max number of concurrent threads within
the call to CreateIoCompletionPort,
does this still work ?

I also thought to use a seperate worker-thread for the timer and use
Your I/O completion port method
for the gui-thread notofications, does this meke sense ?

thanx in advance for furtehr suggestions!

regards,
Hans

Unknown

unread,
Jul 5, 2008, 11:16:26 AM7/5/08
to
On Sat, 5 Jul 2008 04:36:20 -0700 (PDT), hpesata wrote:

>I forgot to mention that we dont use WM_TIMER notifications, instead
>we use a callback function.
>so the message-queue shouldnt be filled up with WM_TIMER
>notifications ?!
>do I miss something here ?

Timer callbacks are called as a result of processing a flag (via
Get/Transalate/Dispatch processing) just like normal timers. That's
why timer callbacks don't work if you don't pump messages. Using a
SetTimer callback does NOT remove dependence upon the message queue,
it simply removes the necessity for your own code to process the
resulting message: the message pump still has to deal with the high
frequency "interrupts" (to coin a phrase). SetTimer Callbacks have no
performance advantages over normal message-based timers, because
they're implemented virtually identically.

--
Bob Moore
http://bobmoore.mvps.org/
(this is a non-commercial site and does not accept advertising)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Do not reply via email unless specifically requested to do so.
Unsolicited email is NOT welcome and will go unanswered.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Joseph M. Newcomer

unread,
Jul 5, 2008, 1:46:37 PM7/5/08
to
See below...

On Sat, 5 Jul 2008 04:36:20 -0700 (PDT), hpesata <hpe...@gmx.at> wrote:

>Hi Joe!
>
>> Windows is not a real-time system.  Keep repeating this until you understand it.  This
>> means that trying to do things at very fine timer resolutions is intrinsically doomed
>> nearly all the time.
>>
>> As already pointed out, you are swamping the thread queue with timer messages, which means
>> that the WM_PAINT never gets a chance.  
>>
>> You can sometimes get away with using the multimedia timers, just bear in mind that the
>> timer callback is always executed in a separate thread of control and consequently cannot
>> touch your windows.  If you PostMessage at the same rate you are using now, you will see
>> the same phenomenon.  You might want to see my essay on the use of I/O Completion Ports to
>> prevent message queue saturation and various umpleasant side effects (delayed user
>> interaction, failure to repaint).
>
>thanx a lot for Your reply!
>
>I forgot to mention that we dont use WM_TIMER notifications, instead
>we use a callback function.
>so the message-queue shouldnt be filled up with WM_TIMER
>notifications ?!
>do I miss something here ?

****
Yes. Callbacks are put in the queue and dispatched by the message pump; the only
difference is that a callback routine is called instead of sending a WM_TIMER, so it is
functionally identical, except that callbacks are much more difficult to handle in MFC,
and therefore are strongly contraindicated.
****


>
>I read Your essay and I have a few questions about it:
>
>as far as I understand I should use Your the MsgWrapper::Post()
>function
>instead of the PostMessage() method to notify my gui-therad about
>changes.
>but You are using 1 for the max number of concurrent threads within
>the call to CreateIoCompletionPort,
>does this still work ?

****
You can use as many threads as you want; in my case, I needed to make sure the result was
FIFO so I had to limit it to one thread. There is no real need to limit the threads if
the stream does not have a FIFO requirement.
****


>
>I also thought to use a seperate worker-thread for the timer and use
>Your I/O completion port method
>for the gui-thread notofications, does this meke sense ?

****
Because timer callbacks are dispatched by the message pump, a separate thread wouldn't buy
you much, unless you did all the heavy computations in the thread and merely notified the
main GUI thread to do the updates based on the precomputed data.

In general, you should avoid the concept of timer callbacks via SetTimer, since they are a
pain to use (they require global variables for the context, which makes them intrinsically
a Bad Idea, but since they give you no advantage over WM_TIMER messages, there's no reason
to ever use them)

If you use a multimedia timer, the callbacks happen in a separate thread. But note that
you can pass in an arbitrary use parameter, so you have no need of *any* global variables.
joe

****


>
>thanx in advance for furtehr suggestions!
>
>regards,
>Hans

hpesata

unread,
Jul 6, 2008, 1:01:19 PM7/6/08
to
Hi Joe!

> You can use as many threads as you want; in my case, I needed to make sure the result was
> FIFO so I had to limit it to one thread.  There is no real need to limit the threads if
> the stream does not have a FIFO requirement.

> Because timer callbacks are dispatched by the message pump, a separate thread wouldn't buy
> you much,  unless you did all the heavy computations in the thread and merely notified the
> main GUI thread to do the updates based on the precomputed data.

thanx again for Your reply!

I understand to stay away from using timers with periods like ours.

As You suggested I am thinking about using a seperate thread and a
seperate FIFO message queue
for our puposes. the seperate therad is adding entries to the seperate
message queue (std::queue
with mutex), the main thread is reading messages out of the FIFO queue
during WM_ENTERIDLE and initiating updates
within the panes. Is there any special advantage in using I/O
completion ports instead of a std::queue ?

regards,
Hans

Joseph M. Newcomer

unread,
Jul 6, 2008, 7:39:36 PM7/6/08
to
See below...

On Sun, 6 Jul 2008 10:01:19 -0700 (PDT), hpesata <hpe...@gmx.at> wrote:

>Hi Joe!
>
>> You can use as many threads as you want; in my case, I needed to make sure the result was
>> FIFO so I had to limit it to one thread.  There is no real need to limit the threads if
>> the stream does not have a FIFO requirement.
>> Because timer callbacks are dispatched by the message pump, a separate thread wouldn't buy
>> you much,  unless you did all the heavy computations in the thread and merely notified the
>> main GUI thread to do the updates based on the precomputed data.
>
>thanx again for Your reply!
>
>I understand to stay away from using timers with periods like ours.
>
>As You suggested I am thinking about using a seperate thread and a
>seperate FIFO message queue
>for our puposes. the seperate therad is adding entries to the seperate
>message queue (std::queue
>with mutex),

****
I would not use a mutex. At the very worst, I would use a CRITICAL_SECTION, since they
are vastly more efficient. Actually, I wouldn't use std::queue at all; I'd use the
PostQueuedCompletionStatus/GetQueuedCompletionStatus of an I/O Completion Port and then I
would not need to do synchronization at all.
****


>the main thread is reading messages out of the FIFO queue
>during WM_ENTERIDLE and initiating updates
>within the panes. Is there any special advantage in using I/O
>completion ports instead of a std::queue ?

****
I find them easier. Why worry about locking if I don't need to?
joe
****

hpesata

unread,
Jul 7, 2008, 2:56:28 AM7/7/08
to
Hi Joe!

> I would not use a mutex.  At the very worst, I would use a CRITICAL_SECTION, since they
> are vastly more efficient.  Actually, I wouldn't use std::queue at all; I'd use the
> PostQueuedCompletionStatus/GetQueuedCompletionStatus of an I/O Completion Port and then I
> would not need to do synchronization at all.
> ****>the main thread is reading messages out of the FIFO queue
> >during WM_ENTERIDLE and initiating updates
> >within the panes. Is there any special advantage in using I/O
> >completion ports instead of a std::queue ?

> I find them easier.  Why worry about locking if I don't need to?

using I/O completion ports is a complete new topic for me,
using them correctly within a multithreaded environment even more ...

as far as I understand Your postings I can use I/O completion ports
with 2 threads,
with one thread posting messages into it and one reading messages out
of it
without the need of any sync object ?!
in this case do I have to use 2 for the max number of threads and will
it still be a FIFO queue then ?

I appreciate Your very valuable comments!

regards,
Hans

Joseph M. Newcomer

unread,
Jul 7, 2008, 9:01:35 AM7/7/08
to
See below...

****
An IOCP is just a FIFO queue. The max number of threads deals with issues about
performance when you have compute-bound response and multiple server threads; if you have
only one server thread (reader of the queue) then the queue is implicitly FIFO, and you
can use 0 for the max threads (I typically always use 0)

There is synchronization, but it is invisible to you so you can ignore it because it
always works right. Note that if you have a queue, you not only need a mutex for the
interlock but you need a semaphore to tell the consumer/server thread that there is
something in the queue (you can't use an event, it doesn't work). So the IOCP embodies
all the logic and you don't need to think about it at all. And while it nominally wants
an LPOVERLAPPED structure, you can treat this as "a pointer to anything" and recast it
when you are doing your own PQCS.
joe
****


>
>I appreciate Your very valuable comments!
>
>regards,
>Hans

hpesata

unread,
Jul 8, 2008, 1:28:54 PM7/8/08
to
Hi Joe!

I implemented the I/O completion port msg queue handling today.
because our app is built out of 1 exe and several MFC extension dlls I
had to adapt Your code a bit.
I created a timer-thread instead of the win32-timer. this thread posts
msgs to the I/O completion port FIFO queue,
within OnIdle() of my CWinApp derived class, I read msgs out of the
FIFO queue and call a callback function which manages the updates
within my panes.
I realized that my msgs are just processed when I move the cursor or
highlight a menu or the likes.
this seems to be the way OnIdle() works. I played around a bit and
found an article which explained
how to use the CWinThread::Run() code within my overridden
CWinApp::Run() and also read msgs out of my FIFO-queue in there.
when I use this, it looks a lot better! the updates within my panes
appear pretty smooth.
I will investigate further into this to see if it is really a usuable
solution.

thanx again for Your support!

regards,
Hans

Joseph M. Newcomer

unread,
Jul 8, 2008, 6:49:14 PM7/8/08
to
That's why I put a WM_TIMER in the main message pump, to eliminate the condition you just
described. It means that there is a maximum queue delay (I chose 250ms) but I could have
set it smaller.
joe

0 new messages