Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.1k views
in Technique[技术] by (71.8m points)

delphi - Make 2 forms able to overlap each other?

I would like to have a seperate form that shows "along" with my main form, so it does not overlap the main form.

Here's an example: Example

Notice how the main program, overlaps the log? I can't figure out how to do that in Delphi.

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answers to this question lie in the very useful Window Features MSDN topic.

The pertinent information is:

An overlapped or pop-up window can be owned by another overlapped or pop-up window. Being owned places several constraints on a window.

  • An owned window is always above its owner in the z-order.
  • The system automatically destroys an owned window when its owner is destroyed.
  • An owned window is hidden when its owner is minimized.

The main form in your app is the owner (in Windows terminology rather than Delphi terminology) of the other popup windows. The first bullet point above implies that the owned windows always appear above the main form (the owner).

Try creating an app with 3 forms and show them all. The .dpr would look like this:

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.

You will see that the main form is always underneath the other two forms, but these other owned forms can be above or below each other. When you minimize the main form they all disappear.

You could if you want make all of your forms top-level unowned windows:

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

And like wise for TPopupForm2 in my example. This would result in all 3 windows having taskbar buttons.

One other approach is to revert to the pre-Vista way of things and make the Application's hidden window be the top-level owner window. You do this by making sure that Application.MainFormOnTaskbar is False. Skip all the CreateParams code and you'll now have a single window on the taskbar and any of your windows can be above any other because the top-level owner window is the hidden window Application.Handle. Of course the downside is that you lose your Aero Peek.

So, I guess what you need to do is to make the main form appear on the taskbar as usual, but ensure that the other forms are not owned (in the Windows sense) by the main form. But they need to be owned to avoid having them in the taskbar. So you can make the hidden application window be the owner using the CreateParams method, like so:

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

Although you state otherwise in the comments, when I do this I find that the popup form is indeed hidden when I minimize the main form. And it is shown again when the main form is restored. Thus I think this does solve your problem completely.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...