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: firstname.lastname@example.org 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: email@example.com Admin: http://delphi.org.nz/mailman/listinfo/delphi Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: unsubscribe