2011-11-01 83 views
4

我有一個應用程序總是至少顯示兩種形式在同一時間。如何在另一個面前移動一個Delphi窗體?

通常我在主窗體的子窗體中有一個工作列表,並在主窗體上顯示相關的詳細信息。其他細節可以使用ShowModal進行管理。

目前的問題是,用戶最近要求可以將主窗體拖到作業列表前面。

就我所見,因爲作業列表表單是在主窗體之後創建的,並從主窗體調用Show來獲取「前」位置。

有沒有什麼辦法可以在運行時更改,即我可以將Active表單設置在前面?

回答

5

注意:在這個答案的其餘部分的術語擁有採用由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在幕後爲你擁有的窗口做了很多工作。如果切換到無主窗口,則可能需要重新生成一些工作。

+0

謝謝你 - 正是需要的。行爲似乎正是我所期待的,讓我們看看請求變更的用戶是怎麼想的。 –

2

只要作業列表形式沒有任何其他窗口的子(即其Parent屬性未設置及其CreateParams()未重寫此方法來設置TCreateParams.WndParent場),並且它正在利用其Show()方法顯示而不是它的ShowModal()方法,那麼用戶應該能夠隨意在兩個窗口之間自由切換。

+0

無模式窗口通常由主窗體擁有,因此始終位於主窗體之上。請注意,擁有我的意思是Windows術語,而不是VCL術語。 –

+0

@David:無模式窗口的所有權取決於Delphi版本。在引入'PopupMode'屬性之前的舊版本中,它們屬於'TApplication'窗口。在較新的版本中,只有當Application.MainFormOnTaskBar爲True時,pmNone才使用MainForm;如果沒有合適的ActiveForm而且Application.MainFormOnTaskBar爲True,則pmAuto只使用MainForm。 ',而且pmExplicit只有在沒有分配'PopupParent'時才使用'MainForm'。 –

+0

顯然,在這種情況下,作業列表窗口歸主窗口所有。從報道的z-順序行爲中可以明顯看出。 –

相關問題