2016-04-28 49 views
1

在我的應用程序中,我有多個表單可以同時顯示,它們都以相同大小的單位顯示磁盤空間(文件,硬盤大小等)。因此,它們都以字節,KB,MB,GB或TB顯示磁盤空間。我還有一個單獨的設置窗體,用戶可以在其中更改顯示大小,他希望以其他形式顯示。一旦用戶在設置表單中單擊確定,我希望所有其他(打開)表單立即更改其大小設置。如何在Delphi中將事件發送到多個表單

每個窗體都有一個受保護的過程SetViewSettings,它負責完成這項工作。它們都是將SetViewSettings定義爲虛擬和抽象的祖先形式的後代。實際顯示的表單會覆蓋祖先的SetViewSettings方法。到目前爲止沒有問題。

因爲我不想打電話給每一個個體的形式(FormX.SetViewSetttings,FormY.SetViewSettings等),我使用了以下解決方案:

procedure TApplicationForms.SetUnits; 
var 
    I: Integer; 
begin 
    for I := 0 to Screen.FormCount - 1 do 
    if Screen.Forms[I] is TfrAncestorInfo then 
     with Screen.Forms[I] as TfrAncestorInfo do 
     acSetUnits.Execute; 
end; 

此過程從SettingsForm作爲所謂的用戶單擊確定。 TFrAncestorInfo是TForm的後代,聲明SetViewSettings方法爲虛擬和抽象。 acSetUnits是一個Action,在TfrAncestorInfo中聲明,它只調用SetViewSettings。這一切都正常,但風險在於創建TFrAncestorInfo的新後代形式,而忘記重寫SetViewSettings方法,在這種情況下,您將遇到「抽象錯誤」異常。

除了單獨列出(調用)所有後代形式之外,是否還有其他方法可以調用窗體中的SetViewSettings方法?我知道消息和事件,但我不知道如何在多種形式中使用這些消息和事件。一般來說:如何直接向所有TFrAncestorInfo後代表單發送消息或爲其生成事件,而無需單獨列出它們?

+0

一種更簡單的解決方案將是溝'acSetUnits.Execute',並使'SetViewUnits'非抽象,但是空的或具有最小的共享代碼,例如'FViewUnits:= Value'。還要拋棄'acSetUnits.Execute',並直接調用SetViewUnits(newUnits)。 –

回答

4

一個選項(還有很多其他可能的選項)將發送一個自定義消息給每個表單。不需要擔心虛擬/抽象重寫,類型檢查等。只有實現消息處理程序的表單纔會對消息作出反應,其餘的則會忽略它。

const 
    WM_SETTINGS_UPDATED = WM_APP + 1; 

procedure TApplicationForms.SetUnits; 
var 
    I: Integer; 
begin 
    for I := 0 to Screen.FormCount - 1 do 
    Screen.Forms[I].Perform(WM_SETTINGS_UPDATED, 0, 0); 
end; 

type 
    TSomeForm = class(TBaseForm) 
    private 
    procedure WMSettingsUpdated(var Message: TMessage); message WM_SETTINGS_UPDATED; 
    protected 
    procedure SetViewSettings; 
    end; 

procedure TSomeForm.WMSettingsUpdated(var Message: TMessage); 
begin 
    SetViewSettings; 
end; 

procedure TSomeForm.SetViewSettings; 
begin 
    //... 
end; 
+0

這確實是,我在找什麼。正如@Gerry所暗示的那樣,解決方案也消除了TAction。 –

+0

你也可以使用'TAction'廣播。例如,這是'TStatusBar.AutoHint'功能的工作方式。當「TApplication.Hint」屬性被設置(例如來自菜單項)並且「TApplication.OnHint」未被分配時,「TApplication」執行在整個應用中廣播的「THintAction」。 'TStatusBar'通過覆蓋虛擬的'TComponent.ExecuteAction()'方法來對廣播做出反應。所以任何Form上的任何'TStatusBar'都可以顯示相同的'Hint'值。您可以播放所有您感興趣的表單可以做出反應的自定義「TAction」。 –

+0

['System.Messaging'](http://docwiki.embarcadero.com/Libraries/en/System.Messaging)是另一種可以在所有平臺上工作的選項,並且不限於表單 –

相關問題