使两种形式能够相互重叠?

时间:2011-03-22 15:30:49

标签: delphi forms vcl tform

我希望有一个单独的表单,与我的主表单“一起”显示,因此它不会与主表单重叠。

以下是一个示例:Example

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

谢谢!

2 个答案:

答案 0 :(得分: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;

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

答案 1 :(得分:-1)

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

mainform.formstyle := fsStayOnTop 

并使用

显示子表单
childform.show;

工作?

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