2015-05-06 15 views
1

在我繼承並正在遷移到XE5的一些傳統D7代碼中,我找到了下面的代碼。用CreateParam的Params.WndParent強制子窗體?

該評論指出它欺騙Windows認爲它是一個子窗體,如果它是從非WinControl創建的。代碼庫中有一處將AOwner作爲nil調用Create。 (表格在那次通話時可用,所以不知道他們爲什麼這麼做......)

對程序員的目標是什麼有什麼建議?

private 
    FParentWinControl: TWinControl; {Don't mess with! Used in CreateParams} 
    procedure TFormX.CreateParams(var params: TCreateParams); override; 
public 
    constructor TFormX.Create(AOwner: TComponent); reintroduce; 
end; 

constructor TFormX.Create(AOwner: TComponent); 
begin 
    if AOwner IS TWinControl then 
    FParentWinControl := TWinControl(AOwner) 
    else 
    FParentWinControl := NIL; 
    inherited Create(AOwner); 
end; { Create } 


procedure TFormX.CreateParams(var params: TCreateParams); 
begin 
    inherited CreateParams(params); 
    if (NOT fCreateParamsHasBeenRun) then 
    begin 
     fCreateParamsHasBeenRun := TRUE; 
     if Assigned(FParentWinControl) then 
     Params.WndParent := FParentWinControl.Handle; {tricks windows into thinking it's a child form} 
    end; 
end; 
+3

'Params.WndParent'是'hWndParent'到'CreateWindowEx',請參閱MSDN文檔以獲取完整說明。除非'TFormX'在樣式中指定了'WS_CHILD'(這似乎不是這種情況),窗口被創建爲擁有者(AOwner)所擁有,它不是孩子。我不知道程序員的想法。雖然他很可能不完全知道他在做什麼。 –

回答

4

此代碼早和鬆散的模仿在Delphi 8添加到TCustomFormPopupMode and PopupParent性假設AOwner是另一種形式,在現代德爾福版本使用這些屬性,如:

constructor TFormX.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    if AOwner Is TCustomForm then 
    PopupParent := TCustomForm(AOwner); 
end; 

而且,使用fCreateParamsHasBeenRun是錯誤的。 CreateParams()每次窗體的窗口被重新創建時都被調用,所以WndParent需要每次都應用,而不是有條件的。如果需要保留CreateParams()邏輯(例如,如果AOwner是非TCustomForm窗口控件),則需要刪除fCreateParamsHasBeenRun

+3

好地方雷米!可能值得說明代碼的效果(擁有的表格「保留在所有者表單的頂部」),以及在原始代碼的註釋中使用術語「孩子」是指涉及z的父母關係而不是任何「遏制」關係(這是什麼讓我在我自己的特殊野雁追逐!)。 – Deltics

+0

感謝你們兩位。 Deltics:是的,留在最前面的是用戶想要做的事情。 – Tom