1

私は自分のプロジェクトのすべてのフォームに配置されているコンポーネントに取り組んでいます。実行時に、コンポーネントにその所有者フォームのOnCloseイベントハンドラーにコードを含めることは可能ですか?つまり、フォームは独自のOnCloseイベントハンドラーをトリガーしますが、コンポーネントには、所有者フォームのOnCloseイベントで実行する追加のイベントハンドラーコードも含まれます。(それはいわゆるベクトル置換ですか?)ありがとうございます。

4

1 に答える 1

7

フォームの元のを格納するフィールドを宣言するコンポーネントを取得する必要がありますOnClose。次に、コンポーネントのコンストラクターで次のことを実行できます。

FOriginalFormClose := (Owner as TForm).OnClose;
(Owner as TForm).OnClose := FormClose;

次に、コンポーネントは次のFormCloseようになります。

TMyComponent.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  // do stuff for this component
  if Assigned(FOriginalFormClose) then
    FOriginalFormClose(Sender, Action);
end;

当然、asキャストはこのコンポーネントをフォームが所有することに結び付けますが、より柔軟性が必要な場合は、簡単にそれに対応できます。

これはあなたが尋ねた質問に対する直接の答えですが、あなたの全体的なデザインに疑問を持たないことは私には許されません。コンポーネントをアプリ内のすべてのフォームに配置する場合は、カスタマイズを含むサブクラスを派生させる必要TFormがあります。次に、アプリ内のすべてのフォームがその共通のベースフォームクラスに基づくようにします。

このアプローチには他にも多くの利点があります。たとえば、@ LachlanGは、私が心から同意する次の非常に適切なコメントを追加します。

コンポーネントがそれ自体のフォームに干渉することは望ましくありません。コンポーネントの大部分は自己完結型のエンティティである必要があり、コンポーネントの所有者を変更すると、Delphiコンポーネントの予想される契約が破られます。

一般的なベースフォームアプローチは、フォームで機能するコードをフォーム内に配置することでこれを解決します。

共通のベースフォームを持つルートをたどる場合は、イベントDoCloseを使用するのではなく、オーバーライドする必要があります。共通の基本クラスまたはコンポーネントを作成するときは、イベント自体ではなくOnClose、常にイベントレイザーを使用してください。DoXXX

于 2012-04-07T06:39:53.033 に答える