オートメーション コントローラでのイベントの処理
COM クライアントの作成:インデックス への移動
タイプ ライブラリがインポートされたオブジェクトのコンポーネント ラッパーを生成すると、生成したコンポーネントに追加されたイベントを使って簡単にイベントに応答できます。 ただし、コンポーネント ラッパーを使用しない場合(またはサーバーが COM+ イベントを使用する場合)は、イベント シンク コードを自分で作成する必要があります。
オートメーション イベントをプログラムで処理する
イベントを処理するには、まず、イベント シンクを定義する必要があります。 これは、サーバーのタイプ ライブラリに定義されているイベント ディスパッチ インターフェイスを実装するクラスです。
イベント シンクを作成するには、イベント ディスパッチ インターフェイスを実装する以下のようなクラスのオブジェクトを作成します。
TServerEventsSink = class(TObject, _TheServerEvents) ...{ declare the methods of _TheServerEvents here } end;
class MyEventSinkClass: TEventDispatcher<MyEventSinkClass, DIID_TheServerEvents> { ...// declare the methods of DIID_TheServerEvents here }
イベント シンクのインスタンスができたら、その存在をサーバー オブジェクトに知らせて、サーバーから呼び出せるようにする必要があります。 それには、以下を引数に渡してグローバル プロシージャ InterfaceConnect を呼び出します。
- イベントを生成するサーバーへのインターフェイス
- イベント シンクが処理するイベント インターフェイスの GUID
- イベント シンクの IUnknown インターフェイス
- サーバーとイベント シンクの接続を表す Longint 値を受け取る変数
{MyInterface is the server interface you got when you connected to the server } InterfaceConnect(MyInterface, DIID_TheServerEvents, MyEventSinkObject as IUnknown, cookievar);
pInterface = CoServerClassName.CreateRemote("Machine1"); MyEventSinkClass ES; ES.ConnectEvents(pInterface);
InterfaceConnect を呼び出した後は、イベント シンクがサーバーと接続し、イベント発生時にサーバーからの呼び出しを受信します。
イベント シンクを解放する前に、接続を終了する必要があります。 それには、上記と同じパラメータ(イベント シンクへのインターフェイスを除く)を渡してグローバル プロシージャ InterfaceDisconnect を呼び出します(最後のパラメータは出力ではなく入力になります)。
InterfaceDisconnect(MyInterface, DIID_TheServerEvents, cookievar);
ES.DisconnectEvents(pInterface);
メモ: イベント シンクを解放する前に、サーバーとの接続が解放されたことを確認する必要があります。 InterfaceDisconnect で起動される接続解除通知にサーバーがどう応答するかわからないので、この呼び出しの直後にイベント シンクを解放すると、サーバーとの競合状態になる可能性があります。 このような問題を防ぐ最も簡単な方法は、サーバーがイベント シンクのインターフェイスを解放するまでデクリメントされない参照カウントをイベント シンク自身に維持管理させることです。
COM+ イベントを処理する
COM+ では、サーバーは特別なヘルパ オブジェクトを使用して、一組の特別なインターフェイス(IConnectionPointContainer と IConnectionPoint)ではなくイベントを生成します。 そのため、TEventDispatcher を継承するイベント シンクを使用できません。 TEventDispatcher は、COM+ イベント オブジェクトではなくこれらのインターフェイスで動作するように設計されているからです。
クライアント アプリケーションでは、イベント シンクを定義するのではなく、サブスクライバ オブジェクトを定義します。 サブスクライバ オブジェクトは、イベント シンクと同様に、イベント インターフェイスの実装を提供します。 イベント シンクとの違いは、サーバーの接続ポイントに接続するのではなく、特定のイベント オブジェクトをサブスクライブすることです。
サブスクライバ オブジェクトを定義するには、COM オブジェクト ウィザードを使用して、イベント オブジェクトのインターフェイスを実装対象として選択します。 メソッドのスケルトンを含んだ実装ユニットがウィザードにより生成されるので、それらのメソッドを完成させてイベント ハンドラを作成できます。
メモ: 実装可能なインターフェイスのリストにイベント オブジェクトのインターフェイスが表示されない場合は、ウィザードを使ってレジストリに追加しなければならない可能性があります。
サブスクライバ オブジェクトを作成したら、イベント オブジェクトのインターフェイスまたはそのインターフェイスの個々のメソッド(イベント)をサブスクライブする必要があります。 選択可能なサブスクリプションは以下の 3 種類あります。
- 一時サブスクリプション: 従来のイベント シンクと同様に、一時サブスクリプションはオブジェクト インスタンスの存続期間に制約されます。 サブスクライバ オブジェクトが解放されると、サブスクリプションは終了し、COM+ はもうそこにイベントを転送しなくなります。
- 永続サブスクリプション: これらは、特定のオブジェクト インスタンスではなくオブジェクト クラスに制約されます。 イベントが発生すると、COM はサブスクライバ オブジェクトのインスタンスを見つけるか起動し、そのイベント ハンドラを呼び出します。 インプロセス オブジェクト(DLL)では、このタイプのサブスクリプションを使用します。
- ユーザーごとのサブスクリプション: このタイプのサブスクリプションは、一時サブスクリプションのセキュリティを強化したものです。 サブスクライバ オブジェクトと、イベントを発生させるサーバー オブジェクトはどちらも同じマシン上で、かつ同じユーザー アカウントで動作している必要があります。