2009-11-03 34 views
5

我們的應用程序曾經使用一種通用的基本形式,所有形式都是爲了繼承。我想擺脫它的原因有很多,從警察的需要,每個人都使用它到與Delphi的VFI執行有關的幾個煩惱。事實證明,它提供的大部分功能都可以通過其他更可靠的方式完成。如何在表單之前放置​​表單?

我不那麼肯定的一個是自動將所有表格放置在呼叫者的中心。所以如果我從主窗體打開對話框A,它應該放在主窗體的中心。如果我從對話框A打開對話框B,它應該放在對話框A的中心等等。

我們通過將基礎表單的Position屬性設置爲poOwnerFormCenter來處理所有這些,並且它工作得非常好。但是,我該如何做這個應用程序?

我想過使用Screen.OnActiveFormChange,但我認爲每當表單獲得焦點時都會發生這種情況。我也想過使用Application.OnModalBegin,但似乎沒有一種明顯的方式來在這個被調用的地方找到表單。

有沒有人試過嗎?

回答

5

那麼,顯然形式繼承是提供解決剛好你試圖解決的問題。任何解決方案可能都會以某種方式結束模仿形式繼承。

您可以做一些簡單的操作,如全局搜索「= class(TForm)」的代碼,並用您現有的基礎表單或僅使用您需要的功能的新的簡化基礎表單類替換TForm類?

如果失敗了,您可以嘗試修改原始的TForm類本身以具有您想要的定位行爲。顯然,修改提供的類是危險的一點。

+1

+1我擺脫了基地,因爲人們沒有使用它,這是一個痛苦的警察。所以我真的想在這裏錯誤的邏輯,但你是對的。我仍然無法找到一個可靠的方法來處理一個或兩個沒有基礎的需求,所以我想我必須把它放回去。我當然認爲我應該跳過繼承的視覺部分,因爲那樣做不好。 – 2009-11-05 08:05:31

+0

我不確定,但可以配置Delphi IDE以至少協助您監督新表單所基於的類。 – 2009-11-05 20:41:35

0

不知道更多關於您的應用程序的信息,我的建議是將定位代碼分別添加到每個表單中 - 沒有基類的優點是它使得某些表單稍微有點不同,它將一個表單的所有邏輯放在一起。

+0

這裏的問題是規模。我們有幾百個軟件包,大部分都包含幾種形式。基類是(我認爲)試圖確保所有表單以一致的方式表現,但隨着歲月的流逝和人們的來去,基地並沒有得到一貫的使用。我試圖強制這種一致性。 – 2009-11-03 13:55:55

4

如果你不打算使用通用的基本形式,那麼我會建議在每個表單上放置一個非可視化組件。該組件可以將你想要的行爲注入到基礎表單中。如果你想在不同的表單上有各種不同的行爲,那麼給你的組件一個角色屬性,該屬性定義表單應該具有的角色,然後它可以根據該角色注入不同的特性。

順便說一句,你也可以有非可視化的表單繼承,這是我爲所有表單創建公共基類的首選方法。它還具有爲表單添加屬性的優點,然後根據這些屬性可以更改表單的角色或行爲。

0

我通常使用SetBounds()過程爲此使用FormShow事件。 使用其他非表單控件,您可以通過覆蓋CMShowing消息來做同樣的事情。

+0

請參閱我對Kragen對該項目規模的回答的評論。如果我無法有效地警告使用共同的基類,那麼任何需要對每種形式進行更改的東西都會死在水中。在較小的項目中,你當然是對的。 – 2009-11-05 08:08:04

0

我把你的OnModalBegin的想法和它一起運行。以下是一個「黑客」,但它似乎工作。要測試只需拖動窗體並單擊按鈕。

procedure TMainForm.Button1Click(Sender: TObject); 
var 
    mForm: TForm; 
begin 
    mForm := TForm.create(self); 
    mform.width := 300; 
    mform.height := 300; 
    mForm.ShowModal; 
    mForm.Free; 
end; 

procedure TMainForm.FormCreate(Sender: TObject); 
begin 
    application.OnModalBegin := modalbegin; 
end; 

procedure TMainForm.FormShow(Sender: TObject); 
begin 
    if Screen.FormCount>1 then begin 
    screen.forms[Screen.FormCount-1].left := round((screen.forms[Screen.FormCount-2].left + screen.forms[Screen.FormCount-2].width/2) - screen.forms[Screen.FormCount-1].width/2); 
    screen.forms[Screen.FormCount-1].top := round((screen.forms[Screen.FormCount-2].top + screen.forms[Screen.FormCount-2].height/2) - screen.forms[Screen.FormCount-1].height/2); 
    application.processmessages; 
    screen.forms[Screen.FormCount-1].Caption := inttostr(screen.forms[Screen.FormCount-1].top)+','+inttostr(screen.forms[Screen.FormCount-1].left); 
    end; 
end; 

procedure TMainForm.ModalBegin(Sender: TObject); 
begin 
    if Screen.FormCount>=0 then 
    screen.forms[Screen.FormCount-1].OnShow := FormShow; 
end; 
相關問題