子表单不得与其父表单重叠

时间:2016-03-25 21:33:05

标签: macos delphi wine

我们有一个Delphi应用程序(XE8),我最近发现它几乎完美地在wine(OSX 10.6)上运行,除了一件事。假设用户在主窗体上选择一个菜单选项,打开另一个窗体(如'File | New ...')。新表单显示,部分涵盖主要表单。问题是没有办法让第一个表单回到顶部。单击主窗体不会像在窗口中那样将其重新显示在子窗体的顶部。如果显示两个子窗体,再次点击一个孩子不会将它带到前台 - 它似乎是可聚焦的(如果你可以抓住它就可以拖动它),但它的任何部分都被覆盖另一种形式仍然存在

当我们使用winebottler和使用交叉应用程序时都会出现这种情况。

我们在装瓶过程中遗漏了一些图书馆吗?或者可能只是完全误解了'windows'在OSX上的工作原理?我们的Windows应用程序设计不佳吗?我们是否需要重新设计应用程序才能使用一个表单(并使用制表符而不是表单启动所有内容)?

编辑:这是一个说明问题的示例delphi项目

program ProjectM;

uses
  Vcl.Forms,
  Unit1m in 'Unit1m.pas' {fmain},
  Unit2m in 'Unit2m.pas' {form2m},

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := False;
  Application.CreateForm(Tfmain, fmain);

  Application.CreateForm(Tform2m, form2m);

  Application.Run;
end.

在unit1中,我们有一个按钮来启动第二个表单

procedure Tfmain.Button1Click(Sender: TObject);
begin
  form2m.show
end;

运行.exe,主窗体显示;按下按钮:新表单覆盖主表单。

在Windows中,单击主窗体的标题栏 - 它将返回到前台。

在winebottler中,单击主窗体的标题栏,它不会恢复;即使看起来标题栏有焦点,表格的其余部分仍然隐藏 - 见截图

enter image description here

1 个答案:

答案 0 :(得分:1)

<强>所有权
问题是你的第二种形式归主体形式所有 拥有的窗口始终显示在其所有者的顶部。

手动设置所有权
解决方案是更改第二个表单的所有权。

首先,您需要禁用自动创建第二个表单并手动执行所有操作:

在菜单中选择:
项目 - &gt;选项 - &gt;形式 选择您的form2并将其从自动创建移动到可用的表单。

enter image description here

现在您需要创建表单:

procedure Tfmain.FormCreate(Sender: TObject);
begin
  Form2:= TForm2.Create(Application); 
end;

葡萄酒顽皮
您可以通过插入CreateParams来强制新表单的WndParent为0:

unit Unit2m;
interface

type 
  TForm2Interposer = class(TForm)
    procedure CreateParams(var Params: TCreateParams); override;
  end;

  TForm2m = class(TForm2Interposer)
  ....
implementation

procedure TForm2Interposer.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := 0;
end;

显示表单
请注意,所有者Application不是您的主要表单。 Application是Delphi用于簿记的隐藏形式。您的mainform和form2现在都有Application作为其所有者。就Z顺序而言,它们具有完全相同的地位。

procedure Tfmain.Button1Click(Sender: TObject);
begin
  form2m.show
end;

无需清理
您已手动创建表单,因此您的直觉是手动销毁表单,但因为Application是表单的所有者。它将负责清理,因此您不必这样做。

procedure Tfmain.FormDestroy(Sender: TObject);
begin
  //Form2.Free;  <<-- The owner does the cleanup.
end;

现在你选择的任何窗口都会出现在最顶层。

<强>说明
这与MainFormOnTaskbar无关,它只是简单的Windows行为:拥有的窗口始终显示在其所有者的顶部。