COM オブジェクトのインターフェイスの定義
ウィザードを使用して COM オブジェクトを作成すると、ウィザードがタイプ ライブラリを自動的に生成します(自動生成しないように COM オブジェクト ウィザードで指定する場合を除く)。 タイプ ライブラリは、ホスト アプリケーションが、オブジェクトが何ができるかを知るための方法を提供します。また、オブジェクト インターフェイスをタイプ ライブラリ エディタを使用して、定義することができます。タイプ ライブラリ エディタで定義するインターフェイスでは、オブジェクトからクライアントに公開されるプロパティ、メソッド、イベントを定義します。
メモ: COM オブジェクト ウィザードで既存のインターフェイスを選択した場合は、プロパティやメソッドを追加する必要はありません。既存のインターフェイスの定義が、その定義元のタイプ ライブラリからインポートされます。代わりに、インポートされたインターフェイスのメソッドを実装ユニット内で探して、それらの本体を記述するだけで済みます。
オブジェクトのインターフェイスへのプロパティの追加
タイプ ライブラリ エディタを使ってオブジェクトのインターフェイスにプロパティを追加すると、そのプロパティの値を読み取るメソッドとプロパティの値を設定するメソッドの両方またはどちらか一方が自動的に追加されます。 タイプ ライブラリ エディタでは、次に、これらのメソッドを実装クラスに追加し、本体を記述して完成できる空のメソッド実装を実装ユニットに作成します。
オブジェクトのインターフェイスにプロパティを追加するには:
- タイプ ライブラリ エディタで、オブジェクトのデフォルト インターフェイスを選択します。デフォルト インターフェイスは、オブジェクト名の前に "I" という文字が付いたものになります。デフォルトを確認するには、タイプ ライブラリ エディタで[CoClass]をクリックしてから[implements]ページを選択し、実装されるインターフェイスの一覧を調べて[デフォルト]としてマークされているものを確認します。
- 読み取り/書き込みプロパティを公開するには、ツールバーの[プロパティの新規作成]ボタンをクリックします。あるいは、[プロパティの新規作成]ボタンの横にある矢印をクリックしたあと、公開するプロパティの種類をクリックします。
- [属性]ページで、プロパティの名前と型を指定します。
- タイプ ライブラリ エディタのツールバーで、[実装の更新]ボタンをクリックします。プロパティ アクセス メソッドの定義とスケルトン実装が、オブジェクトの実装ユニットに挿入されます。
- 実装ユニット内で、プロパティのアクセス メソッドを探します。これらは、Get_<プロパティ名> および Set_<プロパティ名> という形式の名前になっています。オブジェクトのプロパティ値を取得または設定するコードを追加します。このコードでは、アプリケーション内の既存の関数を単に呼び出したり、オブジェクト定義に追加したデータ メンバにアクセスしたり、その他の方法でプロパティを実装したりする可能性があります。
オブジェクトのインターフェイスへのメソッドの追加
タイプ ライブラリ エディタを使ってオブジェクトのインターフェイスにメソッドを追加すると、タイプ ライブラリ エディタにより、今度は、それらのメソッドが実装クラスに追加され、本体を記述して完成できる空の実装が実装ユニットに作成されます。
オブジェクトのインターフェイスを介してメソッドを公開するには:
- タイプ ライブラリ エディタで、オブジェクトのデフォルト インターフェイスを選択します。デフォルト インターフェイスは、オブジェクト名の前に "I" という文字が付いたものになります。デフォルトを確認するには、タイプ ライブラリ エディタで[CoClass]をクリックしてから[implements]ページを選択し、実装されるインターフェイスの一覧を調べて[デフォルト]としてマークされているものを確認します。
- [メソッドの新規作成]ボタンをクリックします。
- [属性]ページで、メソッドの名前を指定します。
- [パラメータ]ページで、メソッドの戻り値の型を指定し、適切なパラメータを追加します。
- タイプ ライブラリ エディタのツールバーで、[実装の更新]ボタンをクリックします。このメソッドの定義とスケルトン実装が、オブジェクトの実装ユニットに挿入されます。
- 実装ユニット内で、新しく挿入されたメソッド実装を探します。このメソッドは完全に空です。このメソッドで表されるタスクを実行するように本体を記述します。
クライアントへのイベントの公開
COM オブジェクトが生成できるイベントは、従来型イベントと COM+ イベントの 2 種類です。
- COM+ イベントの場合は、イベント オブジェクト ウィザードを使って別個のイベント オブジェクトを作成し、サーバー オブジェクトからそのイベント オブジェクトを呼び出すコードを追加する必要があります。
- イベント オブジェクト ウィザードを使用すると、従来型イベントの生成作業の大部分を処理できます。このプロセスを以下に説明します。
メモ: COM オブジェクト ウィザードでは、イベント サポートのためのコードを生成しません。オブジェクトに従来型イベントを生成させる場合は、[オートメーション オブジェクト ウィザード]を使用します。
オブジェクトにイベントを生成させるには:
- [オートメーション オブジェクト ウィザード]で、[イベント サポートのためのコードを生成]オプションをオンにします。イベント インターフェイスおよびデフォルト インターフェイスを含んだオブジェクトが作成されます。このイベント インターフェイスの名前は I<CoClass 名>Events の形式になります。これは外向き(ソース)インターフェイスです。つまり、オブジェクトで実装されるインターフェイスではなく、クライアントで実装されオブジェクトから呼び出されるインターフェイスです。なお、これを確認するには、CoClass を選択して[implements]ページを開き、イベント インターフェイスの[ソース]列に true と表示されていることに気をつけます。[オートメーション オブジェクト ウィザード]では、イベント インターフェイスのほかに、IConnectionPointContainer インターフェイスを実装クラスの宣言部に追加し、イベントを処理するためのクラス メンバもいくつか追加します。これらの新規クラス メンバの中で最も重要なものは FConnectionPoint と FConnectionPoints です。これらは、組み込みの VCL クラスを使って IConnectionPoint インターフェイスと IConnectionPointContainer インターフェイスを実装しています。FConnectionPoint の維持管理は、ウィザードで追加される別のメソッド EventSinkChanged で行われます。
- タイプ ライブラリ エディタで、オブジェクトの外向きイベント インターフェイスを選択します。なお、これは I<CoClass 名>Events という形式の名前を持つものです。
- タイプ ライブラリ エディタのツールバーで[メソッドの新規作成]ボタンをクリックします。イベント インターフェイスに追加した各メソッドは、クライアントで実装される必要があるイベント ハンドラを表しています。
- [属性]ページで、イベント ハンドラの名前を MyEvent などと指定します。
- タイプ ライブラリ エディタのツールバーで、[実装の更新]ボタンをクリックします。これで、オブジェクト実装には、クライアント イベント シンクを受け入れ、イベントの発生時に呼び出すインターフェイスのリストを維持管理するために必要なものがすべて揃いました。これらのインターフェイスを呼び出すには、クライアントで各イベントを発生させるメソッドを作成します。
- コード エディタで、各イベントを発生させるためのメソッドをオブジェクトに追加します。次に例を示します。
unit ev; interface uses ComObj, AxCtrls, ActiveX, Project1_TLB; type TMyAutoObject = class (TAutoObject,IConnectionPointContainer, IMyAutoObject) private . . . public procedure Initialize; override; procedure Fire_MyEvent; { Add a method to fire the event}
- オブジェクトの FConnectionPoint メンバで維持管理されるすべてのイベント シンクを反復処理するように、最後のステップで追加したメソッドを実装します。
procedure TMyAutoObject.Fire_MyEvent;
var
I: Integer;
EventSinkList: TList;
EventSink: IMyAutoObjectEvents;
begin
if FConnectionPoint <> nil then
begin
EventSinkList :=FConnectionPoint.SinkList; {get the list of client sinks }
for I := 0 to EventSinkList.Count - 1 do
begin
EventSink := IUnknown(FEvents[I]) as IMyAutoObjectEvents;
EventSink.MyEvent;
end;
end;
end;
</li>
イベントを発生させてそれをクライアントに通知する必要がある場合は、そのたびに、すべてのイベント シンクにそのイベントをディスパッチするメソッドを呼び出します。
If EventOccurs then Fire_MyEvent; { イベントを発生させるために作成したメソッドを呼び出す。}
if (EventOccurs) Fire_MyEvent; // イベントを発生させるために作成したメソッドを呼び出す。