1

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

假设 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 会恢复到旧的风格,这对我来说现在是不行的。

有任何想法吗?

4

2 回答 2

3

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

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

如果不指定父窗口,如果Application.ModalPopupMode不是pmNone,则使用活动窗体的窗口,否则使用该Application.MainForm窗口。

于 2014-08-13T16:25:14.267 回答
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;

谢谢!

于 2014-08-14T14:18:55.497 回答