I just did that and worked out what the problem is.  It is to do with modal
windows opened while inside my wait loop executing ProcessMessages.

My main form has a timer which needs to continue running at all times.  This
timer is running various functions mostly to do with updating VCL controls.
At certain times, it needs to wait for perhaps a few seconds for a thread to
finish and requires ProcessMessages so the main window continues to update.
I also run the Timer.OnExecute procedure from within this loop so nothing
appears paused.

Generally this works fine when a modal window is loaded, but if I happen to
load a modal window like an open file dialog while inside this wait loop,
ProcessMessages hangs.  If I load the modal window 1 second earlier, then
the wait loop works fine including ProcessMessages.

Likely the ProcessMessages is what caused the modal dialog to load, and the
routine then hangs for a reason I'm sure one of you will know.

Any way to resolve this?

Cheers.


-----Original Message-----
From: Ross Levis [mailto:r...@stationplaylist.com] 
Sent: Tuesday, 2 August 2011 1:54 a.m.
To: 'NZ Borland Developers Group - Delphi List'
Subject: RE: [DUG] Why does this hang?

I can't remember now what problem I was having with
Application.ProcessMessages but this code fixed it while I was testing, and
had to find tune the message numbers.  I failed to comment the code.  I
think it had something to do with other visible non-modal forms.

I may have to re-instate ProcessMessages and see what the problem was.

The wait loop is generally no more than 2 or 3 seconds waiting for a thread
command to finish, but I need the main window to update continuously during
this time.

Ross.

-----Original Message-----
From: delphi-boun...@delphi.org.nz [mailto:delphi-boun...@delphi.org.nz] On
Behalf Of Paul Heinz
Sent: Monday, 1 August 2011 9:30 p.m.
To: edwa...@bigfoot.com; NZ Borland Developers Group - Delphi List
Subject: Re: [DUG] Why does this hang?

Edward wrote: 

> Not 100% sure, but I thought that your loop will not work if 
> the message on top of the queue is not falling into your 
> range, and the message would remain on the queue (due to 
> 'NOREMOVE' flag), and will be peeked everytime afterwards.
>  
> Not sure which message MadExcept uses, it could well be 
> outside of your message ID range.

Yeah, I think Edward is likely spot on here. 

Whatever message this code is preventing from being dispatched (i.e. the
one that previously was causing an error when
Application.ProcessMessages was called instead) is sitting at the top of
the message queue and since it's not being dispatched, it will keep
being returned from PeekMessage and no other windows messages will be
being dispatched.

Windows detects hung applications on the basis of apps failing to
process WM_PAINT messages for a period of time. Now, technically,
WM_PAINT messages are not actually _sent_, they are synthesized based on
your applications dirty regions but only when the message queue is
otherwise empty but the principle is the same. If you're blocked from
processing any messages, you're blocked from processing WM_PAINT.

You might be able to force WM_PAINT calls to be pumped by clever use of
PeekMessage with the PM_QS_PAINT flag to dispacth only WM_PAINT messages
but I've never tried that.

We've modified Forms.pas to allow conditional PM_QS_ family flags to be
passed to Application.ProcessMessages to control the potential
re-entrancy issues that ProcessMessages entails. Being able to process
all outstanding messages without dispatching input is generally far
safer.

Anyway, without knowing more context, I'd be inclined to reinstate the
Application.ProcessMessages and attempt to figure out what the offending
messages that was causing the original problem rather than futzing with
the message loop. 

The Windows message loop is subtle and prone to anger :-) It also
behaves differently under Windows 7 so we had to tweak our conditional
dispatch code to avoid spurious 'hung application' issues that Windows
XP and Vista were fine with.

Essentially, if Windows 7 doesn't see an unconditional PeekMessage being
called regularly, it also consider the app to have hung, even though you
are conditionally pumping WM_PAINT and other messages. A single
unconditional PeekMessage PM_NOREMOVE will satisfy it. Go figure as to
why MS changed this.

Cheers,
  Paul.








_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject:
unsubscribe


_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: delphi@delphi.org.nz
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: 
unsubscribe

Reply via email to