Как вывести OpenDialog, скрытый другим окном, на фронт

У меня есть приложение с несколькими формами и отдельной кнопкой на панели задач для каждой формы.

Допустим, form2 отображает OpenDialog, я кликаю на другое развернутое приложение, покрывающее всю область экрана, затем возвращаюсь к form2, выбирая кнопку на панели задач. Вуаля! OpenDialog скрыт за другим выбранным приложением, и мне нужно нажать на недоступную форму2, чтобы вернуть диалоговое окно вперед. Это действительно раздражает и может запутать пользователя.

Вот некоторый код для иллюстрации проблемы:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show;
end;

end.
________________

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  OpenDialog1.Execute;
end;

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := GetDesktopWindow;
end;

end.

Возможно ли получить ручку видимого opendialog? Раньше это было возможно, но с новым OpenDialog в стиле Vista, если я перехватывал OnDialog. Показывает, что OpenDialog возвращается к старому стилю, который сейчас мне не подходит.

Есть идеи?

2 ответа

TOpenDialog.Execute() имеет необязательный параметр, который позволяет указать родительское окно, в котором диалогу не разрешено отставать:

procedure TForm2.Button1Click(Sender: TObject);
begin
  OpenDialog1.Execute(Self.Handle);
end;

Если вы не указываете родительское окно, окно активной формы используется, если Application.ModalPopupMode не является pmNoneв противном случае Application.MainForm вместо этого используется окно.

Итак, я понял, как вывести диалог на передний план, но есть еще одна проблема: фокус на Form2, а не на диалоге. Если кто-то может сказать мне, как сделать акцент на opendialog вместо Form2 и опубликовать его как ответ, я приму это.

Вот выдержки из кода, которые нужно добавить к оригиналу:

type
  TForm1 = class(TForm)
  private
      procedure WMActivate(var Msg: TWMActivate); message WM_ACTIVATE;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  DialogFormHandle: HWnd;

...

procedure TForm1.WMActivate(var Msg: TWMActivate);
begin
    inherited;

    if DialogFormHandle <> 0 then
    begin
      BringWindowToTop(DialogFormHandle);
      exit;
    end;
end;

...

procedure TForm2.Button1Click(Sender: TObject);
begin
  try
    DialogFormHandle := Handle;
    OpenDialog1.Execute(Handle);
  finally
    DialogFormHandle := 0;
  end;
end;

Спасибо!

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