TOpenDialog moves behind calling form when I close the Windows properties window

delphi, delphi-2006

Solution

In Delphi 2006 and later, `TOpenDialog.Execute()` has an optional `ParentWnd` parameter. When not specified, `Execute()` does some hunting to decide which parent window to use for z-order purposes:

If `Application.ModalPopupMode` is not `pmNone`, `Application.ActiveFormHandle` is used.

If `Application.ModalPopupMode` is `pmNone`, or `Application.ActiveFormHandle` is 0, `Application.Handle` is used instead. In Delphi 2007 and later, with the introduction of the `TApplication.MainFormOnTaskbar` property, if `MainFormOnTaskbar` is true and `Application.MainForm` is assigned, `Application.MainFormHandle` is used instead of `Application.Handle`. `Application.MainFormHandle` triggers the `TApplication.OnGetMainFormHandle` event if assigned. If not assigned, or if it returns 0, `Application.MainForm.Handle` is used.

In Delphi versions up to, and including, 2006, `TOpenDialog` always uses the legacy Win32 API `GetOpenFileName()` function. In Delphi 2007 and later, `TOpenDialog` uses the newer `IFileOpenDialog` API if all of the following criteria are met, otherwise it falls back to `GetOpenFileName()`:

the app is running on Vista or later.

the `Dialogs.UseLatestCommonDialogs` global variable is true.

the `TOpenDialog.Template` property is nil.

no `OnIncludeItem`, `OnClose`, or `OnShow` event handler is assigned to `TOpenDialog`.

When `TOpenDialog` uses `IFileOpenDialog`, `Execute()` respects the specified parent window.

When `TOpenDialog` uses `GetOpenFileName()`, `Execute()` IGNORES the specified parent window if `Application.ModalPopupMode` is `pmNone` and uses `Application.MainFormHandle`/`Application.Handle` instead!

So, to solve your problem in all Delphi versions from 2006 onwards, pass your form's `Handle` to the `ParentWnd` parameter, and set `Application.ModalPopupMode` to a value other than `pmNone`, then the dialog will use your form's window as its parent and thus can never appear behind it. Don't let the VCL decide which parent window to use.

BTW, everything I have said applies to `TSaveDialog` as well.

Problem

I have a form that calls TOpenDialog. When the window comes up I right clicked one of the displayed files and clicked properties. After closing the Windows properties window the open dialog window falls to the bottom of the Z-Order behind the calling form and main application. Using alt+tab (as I have read in similar posts here) will bring the open dialog window to the front, but i'd like a better solution. Most of the research I've done seems to apply only to the TForm class. Is there a way to better control the Z-Order of TOpenDialog? I am using Delphi 2006. I have similar code in a Delphi 2007 application and this problem doesn't occur (if that helps any). Thanks in advance.

Original source