PopupModeプロパティの動作の謎
FormのプロパティにPopupModeというプロパティがあります。このプロパティは複数のFormのZオーダーの管理に影響を与えるプロパティらしいのですがいまいち良く判りません。
Form1(MainForm)とForm2があったとして、Form1のFormStyleがfsStayOnTopの時、Form1からForm2をShowModalで表示する時に違いが見られました。
下記コードで表示した場合、Form2は常にForm1の前面に表示されます。これをPopupModeをpmNoneに変更すると、私の環境だとForm2がForm1の背面に表示されました。Form2がForm1に完全に隠れてしまう位置・大きさで表示された場合ハングアップしたように見えてしまう状態ですね。
procedure TForm1.Button1Click(Sender: TObject); begin Form2 := TForm2.Create(Self); Form2.Left := 0; Form2.Top := 100; Form2.PopupMode := pmAuto; Form2.PopupParent := Nil; Form2.ShowModal; FreeAndNil(Form2); end;
ただ、Form2.PopupParentにForm1を指定したらpmAutoを指定した時と同じように常にForm1の前面に表示されました。
procedure TForm1.Button4Click(Sender: TObject); begin Form2 := TForm2.Create(Self); Form2.Left := 0; Form2.Top := 100; Form2.PopupMode := pmNone; Form2.PopupParent := Self; Form2.ShowModal; FreeAndNil(Form2); end;
Form1をShowModalではなくShowで表示する場合は、PopupModeに何を指定してもForm2は常にForm1の前面に表示されます。
また、PopupModeにpmNone以外を指定した場合、Show、ShowModalどちらでも表示されるFormの位置がLeft,Topプロパティを無視するようになりました。pmNoneの場合は、Left,Topの位置にちゃんとForm2が表示されます。この動作はいまいち理由が良くわかりません。
procedure TForm1.Button2Click(Sender: TObject); var Fm: TForm2; begin Fm := TForm2.Create(Self); Fm.Top := 100; Fm.Left := 0; Fm.PopupMode := pmExplicit; Fm.PopupParent := Self; Fm.Show; end; procedure TForm1.Button3Click(Sender: TObject); var Fm: TForm2; begin Fm := TForm2.Create(Self); Fm.PopupMode := pmNone; Fm.PopupParent := Nil; Fm.Top := 100; Fm.Left := 0; Fm.Show; end;
ヘルプには、pmNoneを指定したらDelphi8以前と同じ動作をすると書いてありますがpmNoneを指定してもForm2は常にForm1の前面に表示されます。すぐに試せる環境が無いのですが、記憶が確かならDelphi7で同じ事をした場合、Form1とForm2はそれぞれアクティブになった方のFormが前面に表示されてたように思います。
Delphi7の頃と同じ動作をさせようと思った場合は、FormのCreateParamsをoverrideしてParams.WndParentを書き換えるのが一番確実かなと思います。
Params.WndParentにApplication.Handleを指定した場合は、Form1とForm2 アクティブになった方のFormが前面になります。また、タスクバーには1つのボタンしか表示されません。
Params.WndParentに0を指定した場合は、Form1とForm2 アクティブになった方のFormが前面になります。また、タスクバーにはForm1とForm2の2つ(Form2を複数表示した場合はその数だけ)のボタンが表示されます。
procedure Form2.CreateParams(var Params: TCreateParams); override; begin inherited; Params.WndParent := Application.Handle; end;