5

我想要一个单独的表单,它与我的主表单“一起”显示,所以它不会与主表单重叠。

这是一个例子:例子

注意主程序如何与日志重叠?我无法弄清楚如何在 Delphi 中做到这一点。

谢谢!

4

2 回答 2

10

这个问题的答案在于非常有用的Window Features MSDN 主题。

相关信息是:

一个重叠或弹出窗口可以由另一个重叠或弹出窗口拥有。拥有对一个窗口有几个限制。

  • 在 z 顺序中,拥有的窗口始终位于其所有者之上。
  • 当所有者被销毁时,系统会自动销毁拥有的窗口。
  • 拥有的窗口在其所有者最小化时被隐藏。

您的应用程序中的主要形式是其他弹出窗口的所有者(在 Windows 术语中,而不是 Delphi 术语中)。上面的第一个要点意味着拥有的窗口总是出现在主窗体(所有者)之上。

尝试创建一个包含 3 个表单的应用程序并将它们全部显示出来。.dpr 看起来像这样:

program OwnedWindows;

uses
  Forms,
  Main in 'Main.pas' {MainForm},
  Popup1 in 'Popup1.pas' {PopupForm1},
  Popup2 in 'Popup2.pas' {PopupForm2};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TMainForm, Main);
  Application.CreateForm(TPopupForm1, PopupForm1);
  Application.CreateForm(TPopupForm2, PopupForm2);
  PopupForm1.Show;
  PopupForm2.Show;
  Application.Run;
end.

您将看到主窗体始终位于其他两个窗体的下方,但这些其他拥有的窗体可以在彼此之上或之下。当您最小化主窗体时,它们都会消失。

如果您想让所有表单成为顶级无主窗口,您可以:

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

在我的示例中,对于 TPopupForm2 也是如此。这将导致所有 3 个窗口都有任务栏按钮。

另一种方法是恢复到Vista 之前的方式,并使应用程序的隐藏窗口成为顶级所有者窗口。为此,请确保 Application.MainFormOnTaskbar 为 False。跳过所有 CreateParams 代码,您现在将在任务栏上拥有一个窗口,并且您的任何窗口都可以在任何其他窗口之上,因为顶级所有者窗口是隐藏窗口 Application.Handle。当然,缺点是你失去了 Aero Peek。

所以,我想你需要做的是让主窗体像往常一样出现在任务栏上,但确保其他窗体不属于主窗体(在 Windows 意义上)。但是需要拥有它们以避免将它们放在任务栏中。因此,您可以使用 CreateParams 方法使隐藏的应用程序窗口成为所有者,如下所示:

procedure TOverlappedPopupForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := Application.Handle;
end;

尽管您在评论中另有说明,但当我这样做时,我发现当我最小化主表单时弹出表单确实被隐藏了。并在主窗体恢复时再次显示。因此,我认为这确实可以完全解决您的问题。

于 2011-03-22T15:35:07.977 回答
-1

我现在还没有打开 Delphi,但会设置

mainform.formstyle := fsStayOnTop 

并显示子窗体

childform.show;

工作?

或者尝试使用SetWindowPos()并将 hWndInsertAfter 属性设置为类似于主窗体上的 HWND_TOPMOST

于 2011-03-22T15:45:04.537 回答