如何将另一个窗口隐藏的打开对话框置于前面

时间:2014-08-13 16:10:58

标签: delphi topendialog createparams bringtofront

我有一个包含多个表单的应用程序,每个表单都有一个单独的任务栏按钮。

让我们说form2显示一个OpenDialog,我点击另一个覆盖整个屏幕区域的最大化应用程序,然后通过选择它的任务栏按钮返回到form2。瞧! OpenDialog隐藏在我选择的其他应用程序后面,我必须单击现在不可访问的form2才能将对话框重新置于前面。这真的很烦人,可能会让用户感到困惑。

以下是一些说明问题的代码:

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的句柄?它曾经是可能的,但是如果我捕获OnDialogShow,那么使用新的Vista风格OpenDialog,OpenDialog将恢复到旧式,这对我来说是不行的。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

TOpenDialog.Execute()有一个可选参数,可让您指定不允许对话框落后的父窗口:

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

如果您没有指定父窗口,则Application.ModalPopupMode不是pmNone时会使用活动表格的窗口,否则会使用Application.MainForm窗口。

答案 1 :(得分:0)

所以我想出了如何将对话框放在前面,但仍然存在一个问题:焦点在于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;

谢谢!