2016-04-28 30 views
1

私のアプリケーションでは、複数のフォームが同時に表示され、同じサイズの単位でディスクスペース(ファイル、ハードディスクサイズなど)が表示されます。だから、それらのすべては、バイト、KB、MB、GBまたはTBのディスク容量を表示します。私はまた、別のフォームで必要なディスプレイのサイズを変更することができる別の設定フォームを持っています。ユーザーが設定フォームで[OK]をクリックすると、他のすべての(開いている)フォームですぐにサイズ設定が変更されます。複数のフォームを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から呼び出されますユーザーは[OK]をクリックします。 TFrAncestorInfoは、TFormの子孫であり、SetViewSettingsメソッドを仮想および抽象として宣言します。 acSetUnitsはTfrAncestorInfoで宣言されたActionで、SetViewSettingsだけを呼び出します。これはうまくいきますが、SetViewSettingsメソッドをオーバーライドするのを忘れている間、TFrAncestorInfoの新しい子孫フォームを作成するリスクがあります。この場合、「抽象エラー」例外が発生します。

すべての子孫フォームを個別に表示(呼び出し)せずに、フォームでSetViewSettingsメソッドを呼び出す方法はありますか。私はメッセージや出来事を知っていますが、私は複数形の状況でこれらをどのように使うべきか分かりません。一般的に、TFrAncestorInfoのすべての子孫フォームに対して、個別にリストすることなく直接メッセージを送信したり、イベントを生成したりするにはどうすればよいですか?

+0

簡単な解決策は、例えば、 'acSetUnits.Execute'を捨てすること、および'非抽象SetViewUnits'が、空または最小限の共有コードのいずれかになるだろう'FViewUnits:= Value'。また、 'acSetUnits.Execute'を捨て、' SetViewUnits(newUnits) 'を直接呼び出してください。 –

答えて

4

1つのオプション(他にも多くのオプションがあります)は、すべてのフォームにカスタムメッセージを送信することです。仮想/抽象オーバーライド、型チェックなどについて心配する必要はありません。メッセージハンドラを実装するFormsだけがメッセージに反応し、残りは単純に無視されます。

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() 'メソッドをオーバーライドすることによってその放送に反応します。つまり、どのフォーム上のどのTStatusBarも同じ 'Hint'値を表示できます。あなたは興味のあるすべてのフォームが反応できるカスタム 'TAction'を放送することができます。 –

+0

['System.Messaging'](http://docwiki.embarcadero.com/Libraries/en/System.Messaging)は、すべてのプラットフォームで動作する別のオプションであり、フォームには制限されません –

関連する問題