第 27 章 C++ による VISIO アプリケーションのプログラミング
Event オブジェクトを使用して、Visio® のイベントを C++ プログラムで処理することができます。Event オブジェクトでは、イベントとアクションが対になっています。このアクションは、指定したイベントが発生したときにアドオンを実行するか、別のオブジェクトに通知を送るかのどちらかになります。この通知される側のオブジェクトをシンク オブジェクトと呼びます。Microsoft Visual Basic プログラムでの Event オブジェクトの動作、およびその実装方法の詳細については、「第 21 章 Visio のイベントの処理」を参照してください。
Visio エンジンは、コントロールがコントローラ コンテナに提供する標準の IConnectionPoint プロトコルを使って、Visual Basic の WithEvents と同様の形式のイベント処理をサポートします。C++ プログラムは、Event オブジェクトの代わりに IConnectionPoint プロトコルを使って Visio のインスタンスからのイベントを受け取ることができますが、その場合、そのイベントを渡す側の Visio オブジェクトに対して宣言されているイベント セット インターフェース全体を実装する必要があります。IConnectionPoint とその関連するインターフェースの詳細については、COM のマニュアルを参照してください。
このセクションでは、EventList.Add または EventList.AddAdvise を呼び出して作成された Event オブジェクトを使って C++ プログラムで Visio イベントを受け取る方法を説明します。IConnectionPoint は Visio 固有のプロトコルですが、C++ プログラムにイベント セット インターフェース全体を実装する必要はありません。C++ プログラムでは、イベント セット内のすべてのイベントではなく、IConnectionPoint が必要とするイベントだけを登録できます。
このセクションの内容...
C++ プログラムでの Visio のイベントの処理は、Microsoft Visual Basic プログラムでの処理と同じ方法で実装できますが、次の点が異なります。
STDMETHOD(VisEventProc) ( |
|
|
AddAdvise メソッドを呼び出して Event オブジェクトを作成する場合、シンク オブジェクトの IUnknown または IDispatch インターフェースにポインタを渡します。
独自のシンク オブジェクトを作成する代わりに、Visio 2000 で提供されている CVisioAddonSink クラスを使用することができます。このクラスは、\DVS\Libraries\C-CPP\Vao_inc にある Addsink.h ファイル内で宣言されています。
CVisioAddonSink を使用するには
サンプル プログラム Generic.cpp は CVisioAddonSink クラスを使用して、DocumentCreated と ShapeAdded の 2 つのイベントを処理します。このプログラムは、それぞれのイベントについてコールバック関数を宣言しています。コールバック関数のシグネチャは、Addsink.h で定義されている VISEVENTPROC に適合していなければなりません。下の例は、宣言の 1 つを示しています。この関数の実装については、Generic.cpp を参照してください。
HRESULT STDMETHODCALLTYPE ReceiveNotifyFromVisio (
IUnknown FAR* |
IpSink, |
このプログラムは、シンク オブジェクトを作成するために、Application オブジェクト (CVisioapplication 型変数の app にあたる) の EventList コレクションを取得し、CoCreateAddonSink を呼び出してシンク オブジェクトを作成し、EventList オブジェクトに対して AddAdvise を呼び出して Visio のインスタンスに Event オブジェクトを作成します。プログラムはフラグ bFirstTime に TRUE を設定します。これは、Event オブジェクトがプログラムの実行中に 1 度だけ作成されるようにするためのフラグです。後で参照できるように、Event オブジェクトの ID が静的変数 stc_nEventID に格納されます。AddAdvise の呼び出しによってシンク オブジェクトへのもう 1 つの参照が作成されるので、プログラムは pSink を解放できます。
static long |
stc_nEventID = visEvtIDInval; |
if (bFirstTime && (SUCCEEDED(app.EventList(eList))))
{
bFirstTime= FALSE;
if (SUCCEEDED(CoCreateAddonSink(ReceiveNotifyFromVisio, &pSink)))
{
if (SUCCEEDED(eList.AddAdvise(visEvtCodeDocCreate,
VVariant(pSink), VBstr(""), VBstr(""), event)))
{
event.ID(&stc_nEventID);
}
//If AddAdvise succeeded, Visio now holds a reference to the sink object
//via the event object, and pSink can be released
pSink->Release();
pSink= NULL;
}
...
}
AddAdvise によって作成された Event オブジェクトは、Event オブジェクトが削除され、ソース オブジェクトへのすべての参照が解放されるか、Visio のインスタンスが閉じられるまで持続します。Visio のインスタンスが終了する前にプログラムでなんらかの後処理を行わなければならない場合は、BeforeQuit イベントを使います。
Visio ライブラリ (VSL) で CVisioAddonSink が使用されている場合、そのアンロード ハンドラは Event.Delete を呼び出す必要があります。