我有一個應用程序總是至少顯示兩種形式在同一時間。如何在另一個面前移動一個Delphi窗體?
通常我在主窗體的子窗體中有一個工作列表,並在主窗體上顯示相關的詳細信息。其他細節可以使用ShowModal進行管理。
目前的問題是,用戶最近要求可以將主窗體拖到作業列表前面。
就我所見,因爲作業列表表單是在主窗體之後創建的,並從主窗體調用Show來獲取「前」位置。
有沒有什麼辦法可以在運行時更改,即我可以將Active表單設置在前面?
我有一個應用程序總是至少顯示兩種形式在同一時間。如何在另一個面前移動一個Delphi窗體?
通常我在主窗體的子窗體中有一個工作列表,並在主窗體上顯示相關的詳細信息。其他細節可以使用ShowModal進行管理。
目前的問題是,用戶最近要求可以將主窗體拖到作業列表前面。
就我所見,因爲作業列表表單是在主窗體之後創建的,並從主窗體調用Show來獲取「前」位置。
有沒有什麼辦法可以在運行時更改,即我可以將Active表單設置在前面?
注意:在這個答案的其餘部分的術語擁有採用由Windows documentation使用的含義。這與VCL中相同術語的含義不同。
發生的事情是,您的工作列表窗口是頂級擁有的窗口。
被擁有的位置對窗口有幾個限制。
- 一個擁有的窗口始終在z所有者的上方。
- 系統在其擁有者被銷燬時自動銷燬擁有的窗口。
- 擁有窗口在其所有者最小化時隱藏。
如果你想你的工作列表窗口是能夠被在Z順序主窗口下方,它不能由主窗口擁有。你可以做到這一點,如下所示:
class TJobListForm = class(...)
protected
procedure CreateParams(var Params: TCreateParams); override;
...
procedure TJobListForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := Application.Handle;
end;
這使得作業列表窗口中隱藏的應用程序窗口擁有的頂級窗口。或者像這樣:
procedure TJobListForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := 0;
end;
這使得作業列表窗口成爲一個無主窗口的頂層窗口。因此它現在在任務欄中收到一個按鈕。
進行此類更改將對您的應用程序產生深遠影響。上面列表中的第二個和第三個項目符號是顯而易見的影響。最小化窗口的行爲以及與任務欄的交互也會受到影響。我只在這裏表面劃傷。你可能會發現,讓你的工作列表窗口不再被主窗口所擁有,對你的程序有相當大的影響。你會發現Windows在幕後爲你擁有的窗口做了很多工作。如果切換到無主窗口,則可能需要重新生成一些工作。
只要作業列表形式沒有任何其他窗口的子(即其Parent
屬性未設置及其CreateParams()
未重寫此方法來設置TCreateParams.WndParent
場),並且它正在利用其Show()
方法顯示而不是它的ShowModal()
方法,那麼用戶應該能夠隨意在兩個窗口之間自由切換。
無模式窗口通常由主窗體擁有,因此始終位於主窗體之上。請注意,擁有我的意思是Windows術語,而不是VCL術語。 –
@David:無模式窗口的所有權取決於Delphi版本。在引入'PopupMode'屬性之前的舊版本中,它們屬於'TApplication'窗口。在較新的版本中,只有當Application.MainFormOnTaskBar爲True時,pmNone才使用MainForm;如果沒有合適的ActiveForm而且Application.MainFormOnTaskBar爲True,則pmAuto只使用MainForm。 ',而且pmExplicit只有在沒有分配'PopupParent'時才使用'MainForm'。 –
顯然,在這種情況下,作業列表窗口歸主窗口所有。從報道的z-順序行爲中可以明顯看出。 –
謝謝你 - 正是需要的。行爲似乎正是我所期待的,讓我們看看請求變更的用戶是怎麼想的。 –