How to show a modal form on top of its owner form (its owner is set to fsStayOnTop or not), just as TOpenDialog does

Суммирование:

Please see the helpful comments below from Craig and Sertac.

================================================== ====

As shown in the following minimized code, TForm10 установлено быть fsStayOnTop, TForm10.btnTryDlgClick вызов dlgOpen1.Execute, and the dialog shown is as expected. Тем не менее, когда я звоню TForm11.Create(Self).ShowModal внутри TForm10.btnTryFormClick, the form is hidden behind the TForm10. I am wondering how to understand this behavior, and why standard TOpenDialog can show as expected? Любой комментарий приветствуется!

PS: One workaround is to override the CreateParams procedure of TForm11, and set Params.wndParent to 0. But it looks to me that window hierarchy will be broke using this workaround.

  procedure TForm11.CreateParams(var Params: TCreateParams); // override;
  begin
    inherited;
    params.wndParent := 0;
  end;

PS: Another workaround is mentioned by Remy in the below relevant SO pages: setting the modal Form's PopupParent property to be the StayOnTop Form, But in the followed comments, Sertac mentioned this workaround will also break window hierarchy.

PS: Возможно, соответствующие страницы SO:
Модальные формы, скрытые формами fsStayOnTop
Как я могу не дать FindDialog оставаться на вершине (Delphi)?
Как убедиться, что диалог всегда находится перед главным окном
Форма скрыта за другими формами при вызове ShowModal
Сделать 2 формы способными перекрывать друг друга?
Несколько приложений Delphi и диалоговых окон
Недавно созданное модальное окно теряет фокус и становится недоступным в Windows Vista
Delphi - Как предотвратить перемещение Forms/MsgBoxes по предыдущей форме?
Как разрешить Delphi вторичные формы за основной формой
Поддельный модальный диалог с помощью Show?
Delphi MainFormOnTaskBar Модальная ошибка Windows

Источник для Unit10:

    unit Unit10;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;

    type
      TForm10 = class(TForm)
        btnTryDlg: TButton;
        dlgOpen1: TOpenDialog;
        btnTryForm: TButton;
        procedure FormCreate(Sender: TObject);
        procedure btnTryDlgClick(Sender: TObject);
        procedure btnTryFormClick(Sender: TObject);
      end;

    var
      Form10: TForm10;

    implementation

    {$R *.dfm}

    uses
      Unit11;

    procedure TForm10.FormCreate(Sender: TObject);
    begin
      FormStyle := fsStayOnTop;
    end;

    procedure TForm10.btnTryDlgClick(Sender: TObject);
    begin
      dlgOpen1.Execute;
    //  dlgOpen1.Execute(Self.Handle);
    end;

    procedure TForm10.btnTryFormClick(Sender: TObject);
    begin
      TForm11.Create(Self).ShowModal;
    end;

    end.

DFM для Unit10:

    object Form10: TForm10
      Left = 0
      Top = 0
      Caption = 'Form10'
      ClientHeight = 255
      ClientWidth = 414
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      OnCreate = FormCreate
      PixelsPerInch = 96
      TextHeight = 13
      object btnTryDlg: TButton
        Left = 32
        Top = 24
        Width = 153
        Height = 201
        Caption = 'Try dialog'
        TabOrder = 0
        OnClick = btnTryDlgClick
      end
      object btnTryForm: TButton
        Left = 224
        Top = 24
        Width = 153
        Height = 201
        Caption = 'btnTryForm'
        TabOrder = 1
        OnClick = btnTryFormClick
      end
      object dlgOpen1: TOpenDialog
        Left = 96
        Top = 168
      end
    end

Источник для Unit11:

    unit Unit11;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;

    type
      TForm11 = class(TForm)
      end;


    implementation

    {$R *.dfm}

    end.

DFM для Unit11:

    object Form11: TForm11
      Left = 0
      Top = 0
      Caption = 'Form11'
      ClientHeight = 183
      ClientWidth = 203
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
    end

1 ответ

Решение

Установите свойство PopupParent модальной формы, точно так же, как предложил Реми. Это будет привязывать диалог к ​​форме StayOnTop, что и делает метод Execute диалога. Я не уверен, откуда поступают комментарии Sertac, но использование PopupParent правильно устанавливает иерархию окна, поэтому диалог всегда будет выше формы StayOnTop.

Другие вопросы по тегам