2

My application have several MDI forms and one of this form have child modal form with detailed information. So, when I open this modal form from my MDI form, I click 'browse' button and create OpenFileDialog. Everything works fine, except when I ALT+TAB. When I ALT+TAB and then ALT+TAB back to my application I see that OpenFileDialog (messageboxes too) is BEHIND my modal window, but in fron of MDI window. There is no StayOnTop or something like that. Only way to bring back OpenDialog in front of all windows is to make second ALT+TAB to my application. This causes Dialog to pop in front of all other windows.

What can I do to prevent Dialog from hiding behind my Modal form? Any suggestion?

I use delphi7 and can't use greater version

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Darthman
  • 457
  • 4
  • 21
  • http://stackoverflow.com/q/5660468/62576 – Ken White Jul 24 '13 at 10:54
  • 3
    Which version of Delphi? How are you showing the dialog? Older versions of Delphi sometimes failed to set the dialog's window owner. – David Heffernan Jul 24 '13 at 10:58
  • There is no StayOnTop forms and I forgot to mention that I use delphi7 and can't use greater version. – Darthman Jul 24 '13 at 10:59
  • Delphi 7 sets the dialog's window owner to be `Application.Handle`. Not sure the mechanism for the problem, but you really want the window owner to be the form that invoked the dialog. If I were you I'd call `GetOpenFileName` directly and avoid `TOpenDialog`. Or find a way to patch the VCL code so that it sets the window owner properly. So, you could subclass `TOpenDialog`, override, `TaskModalDialog` and fix the window owner in the `OPENFILENAME` struct that is passed. – David Heffernan Jul 24 '13 at 11:19
  • OK, the mechanism is probably as follows. When you ALT+TAB, for whatever reason, your main form is brought to the front, but the hidden Application window is not. And so there's nothing to bring your dialog to the front. But if the dialog's window owner chain led to the main form, then the dialog would come to the front since windows are always on top of their owners. – David Heffernan Jul 24 '13 at 11:27
  • @DavidHeffernan but the latter perhaps may be fixed by bringing application to the front in events of TScreen? – Arioch 'The Jul 24 '13 at 11:29

1 Answers1

6

I'm hypothesising that the issue is related to window ownership. In Delphi 7, file dialogs have the hidden application window as their window owner. But the window owner really needs to be the window of the active form.

There are plenty of ways to fix this, but perhaps the simplest is to subclass TOpenDialog and override its TaskModalDialog like this:

function TMyOpenDialog.TaskModalDialog(DialogFunc: Pointer;
  var DialogData): LongBool;
var
  hwndOwner: HWND;
begin
  hwndOwner := Screen.ActiveForm.Handle;
  if hwndOwner = 0 then
    hwndOwner := Application.MainForm.Handle;
  if hwndOwner = 0 then
    hwndOwner := Application.Handle;
  TOpenFilename(DialogData).hwndOwner := hwndOwner;
  Result := inherited TaskModalDialog(DialogFunc, DialogData);
end;

I don't have Delphi 7 at hand to test this, but I'm reasonably confident that something along these lines (with perhaps some tweaking of the hwndOwner choice) will sort it out.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490