I have a Delphi 2006 app which can pop up a modal dialog in response to an error condition. It seems to get itself into a state where one of these modal dialogs is open, positioned in front of the main form, but neither form is responding to messages. Clicking on either gives a "bonk". The app is running fine, the UI is updating the main form, but you can't do anything. I guess there is most likely another modal dialog under the main form. Whether it is one of mine or one from Windows I have no idea.
Other points:
- the app responds to keyboard shortcuts OK. One of these shortuts shuts down the app gracefully and this worked. I have been unable to reproduce the situation since.
- the app has a tray icon. This responds to right mouse clicks. If I minimize the app from here the main form minimizes and leaves the modal dialog displayed, still without focus. If I restore the main form, things are as they were, with neither window having focus. Alt-tab has similar results.
- platform is Windows 7
- I call DisableProcessWindowsGhosting before any forms are created
I open the modal dialogs with
ModalDialog.PopupParent := MainForm ; ModalDialog.ShowModal ;
I postpone these error dialogs if other modal dialogs are open:
if (Application.ModalLevel = 0) then {open modal dialog}
My question has two parts:
Is there a way of programmatically finding out what window has focus? I could then take some action for this scenario or a last resort I could them provide a shortcut key to bring it to the front or take some evasive action (depending on the dialog) like set the ModalResult to mrCancel.
How can this situation arise? Normally when I get a modal dialog behind the main form (I can do that by getting the modal dialog to open, minimizing the app from the tray icon, then restoring the app again - the app main form restores in front of the dialog, with the dialog still retaining focus), I can bring it to the front again by clicking on the tray icon, or close it with the Esc
key but it didn't work in this case.
**UPDATE**
Misha's fix worked apart from non-delphi dialogs like TSaveDialog. I was able to get them to work as well by adding Application.ModalPopupMode := pmAuto ;
just before the call to Execute
.
By "got it to work" I mean that the save dialog was in front after the following sequence:
- open save dialog
- minimize app from tray icon
- restore app from tray icon
whereas it was behind the main form without the ModalPopupMode := pmAuto
.
So I'm hoping these changes will help the (as yet unreproduced) problem.