前のトピック     次のトピック

第 27 章 C++ による VISIO アプリケーションのプログラミング

セクション 4   Visio ライブラリ

Visio® のライブラリ (VSL) は、実行時に Visio エンジンによってロードされる特殊なダイナミック リンク ライブラリです。VSL は、1 つ以上の Visio アドオン (オートメーションを使用して Visio インスタンスを制御するプログラム) を実装できます。

VSL によって実装されたアドオンは、実行可能ファイル (EXE) または図面の Microsoft Visual Basic for Applications (VBA) プロジェクトによって実装されたアドオンとまったく同じ方法で Visio のオブジェクトを対話的に処理することができ、ユーザーもそれと同じ操作を行うことができます。VSL は Visio インスタンスと同じプロセス内で実行されるので、実行可能ファイルに実装されたアドオンよりも、VSL に実装されたアドオンのほうがパフォーマンスと統合性において優れています。ただし、VSL は実行可能ファイルのように Windows のエクスプローラから実行することはできません。

Visio では、[アドオン] パスまたは [スタートアップ] パスにある、拡張子が .vsl のファイルが VSL であるとみなされます。VSL をインストールするには、Visio の [アドオン] パスまたは [スタートアップ] パスで指定されているディレクトリにファイルをコピーします。次に Visio のインスタンスを実行したときに、その VSL によって実装されたアドオンが Visio のインスタンスで使用できるようになります。

VSL を開発するために必要なファイルは、\DVS\Libraries\C-CPP フォルダにあります。このフォルダの内容は以下のとおりです。

このセクションの内容...

Visio ライブラリの長所

Visio ライブラリのアーキテクチャ

アドオンの宣言と登録

アドオンの実行

Visio ライブラリの長所

条件が同じであれば、VSL は実行可能ファイルよりも処理速度が優れています。VSL は DLL なので、このライブラリを使用する Visio インスタンスのプロセス領域にロードされます。実行可能ファイルから Visio インスタンスを呼び出す場合とは異なり、VSL から Visio インスタンスを呼び出してもプロセスの境界を越えることはありません。

また、VSL は Visio インスタンスと同じプロセスで実行されるので、Visio インスタンスが実行しているプロセスに対してモーダルなダイアログ ボックスを簡単に開くことができます。2 つの実行可能ファイル (アドオンと Visio のインスタンス) が実行されているとき、一方の実行可能ファイル側で、他方に対してモーダルなダイアログ ボックスを開くことは困難です。アドオンの実行可能ファイルはダイアログ ボックスを表示できますが、ダイアログ ボックスが開いているときにユーザーが Visio のウィンドウをクリックすると、Visio の状態が変化してしまうからです。

また、Visio ライブラリでは、Windows コレクションの Add メソッドを使って、ソリューションによって定義されるウィンドウを Visio ウィンドウの子ウィンドウとして簡単に追加できます。そのためには HWND を作成し、Windows.Add によって追加されたウィンドウからの WindowHandle32 を親 HWND として使用します。異なるプロセスからの HWND を親ウィンドウとして使用する方法は、埋め込み先編集以外では使用できません。

TOP へ

Visio ライブラリのアーキテクチャ

VSL は、VisioLibMain という名前で要求されたエントリ ポイントをエクスポートする標準的な DLL です。

Visio インスタンスは、VSL のロードと解放を、それぞれ LoadLibraryFreeLibrary を使って行います。VSL が Visio の [スタートアップ] フォルダにインストールされていない場合、VSL がいつロードされるかは決まっていません。[スタートアップ] フォルダに以外の場所にある VSL は、必要なときにだけ Visio インスタンスによってロードされます。Visio インスタンスが VSL をロードした場合、インスタンスがシャットダウンされるまでその VSL に対して FreeLibrary を呼び出しません。

VDLLmain.c ファイルは、デフォルトの DllMain 関数を実装します。DllMain は、Windows が DLL をロードおよびアンロードするときに呼び出す標準的な DLL エントリ ポイントです。Vao.c ファイルには、ほかの便利な関数も実装されています。そのいくつかを以下に示します。

Visio インスタンスが VSL をロードした後、このインスタンスは必要に応じて VSL の VisioLibMain プロシージャを呼び出します。Visio インスタンスが VisioLibMain に渡す引数の 1 つに、呼び出しの理由を VSL に知らせるメッセージ コードがあります。すべての Visio メッセージは Vao.h で定義されています。

VisioLibMain のプロトタイプは Vao.h では次のように定義されています。

typedef WORD VAORC, FAR* LPVAORC;
typedef WORD VAOMSG, FAR* LPVAOMSG;

#define VAOCB __cdecl

//Visio add-on return code
//Visio add-on message code

//Visio add-on callback procedure

//The prototype of VisioLibMain should conform to VAOFUNC
typedef VAORC (VAOCB VAOFUNC) (VAOMSG,WORD,LPVOID);

標準的な VisioLibMain 関数は、次のようなコードで記述されます。

#include "vao.h"
VAORC VAOCB VisioLibMain (VAOMSG wMsg, WORD wParam, LPVOID lpParam)
     {
     VAORC result = VAORC_SUCCESS;
     switch (wMsg)
          {
          case V2LMSG_ENUMADDONS:
               //Code to register this VSL's add-ons goes here
               break;
          case V2LMSG_RUN:
               //Code to run add-on with ordinal wParam goes here
               break;
          default:
               //Trigger generic response to wMsg
               //Helper procedures VAOUtil_DefVisMainProc and VLIBUTL_hModule
               //are implemented in vao.c
               result = VAOUtil_DefVisMainProc(wMsg, wParam, lpParam, VLIBUTL_hModule());
               break;
          };
     return result;
     }

VisioLibMain は、V2LMSG_RUN メッセージと V2LMSG_ENUMADDONS メッセージを処理します。他のメッセージは、一般的なメッセージ応答を実装する VAOUtil_DefVisMainProc 関数によって処理されます。VLIBUTL_hModule は VSL のモジュール ハンドルになります。

TOP へ

アドオンの宣言および登録

インスタンスは、VSL によって実装されたアドオンの詳細を取得するために、VSL の VisioLibMain に V2LMSG_ENUMADDONS メッセージを送ります。

Lib.c ファイルにはサンプルの VSL が実装されています。このファイルには、VSL がアドオンを登録する方法を示すソース コードがあります。コードは、2 つの部分に分かれています。はじめに、Lib.c でアドオンを記述するデータ構造体を定義しています。次に、V2LMSG_ENUMADDONS メッセージへの応答として、このデータ構造体を、メッセージを発行した Visio インスタンスに渡します。

Lib.c はアドオンを 1 つ実装します。ファイルの先頭の近くに、次のようなコードが記述されています。

#define DEMO_ADDON_ORDINAL 1
PRIVATE VAOREGSTRUCT stc_myAddons[] =
{     

{
DEMO_ADDON_ORDINAL,
VAO_AOATTS_ISACTION,
VAO_ENABLEALWAYS,
0,
0,
"VSL Automation Demo",
},


//Ordinal of this add-on
//This add-on does things to Visio
//This add-on is always enabled
//Invoke on mask
//Reserved for future use
//The name of this add-on

};

VAOREGSTRUCT 構造体は Vao.h で宣言されています。この構造体のそれぞれのフィールドの詳細については、Vao.h 内のコメントおよび宣言を参照してください。

Visio のインスタンスは、VSL にアドオンの実行を指示するとき、実行するアドオンをその序数によって指定します。序数は、ファイルの中のアドオンを識別する一意な値です。 配列 stc_myAddons は序数が 1 (DEMO_ADDON_ORDINAL) であるアドオンを宣言しています。2 つのアドオンを実装しているソース ファイルの場合は、この stc_myAddons には 2 つのエントリが含まれ、それぞれのエントリは一意な序数を持ちます。

Lib.c で宣言されたアドオンは、Visio のユーザー インターフェースに "VSL Automation Demo." という文字列で表示されますが、独自のアドオンを作成する場合は、コード内でアドオンの名前を宣言しません。代わりに、文字列ソースからアドオン名を読みこみ、その名前で VAOREGSTRUCT 構造体内のアドオン名を動的に初期化します。

定数 VAO_ENABLEALWAYS によって、このアドオンは Visio インスタンスで常に有効となります。アドオンを有効にする定数は他にもあります。たとえば、図面が開いているときにだけ実行したいアドオンがあります。そのようなアドオンでは、定数 VAO_NEEDSDOC を宣言します。Visio インスタンスは、図面が開いていないときはこのアドオンを無効とみなします。つまり、このアドオンが実行されているときは図面が開いていると判断することができます。Vao.h では、VAO_NEEDSDOC と同様の、アドオンを有効または無効にする静的定数がいくつか宣言されています。

Vao.h には、VAO_ENABLEDYNAMIC という定数もあります。Visio のインスタンスは、アドオンが有効かどうかを判断する場合に、動的に有効にできるアドオンに V2LMSG_ISAOENABLED を送ります。アドオンは、そのときの状態に従って、有効か無効かを通知することができます。

VAOREGSTRUCT 構造体では、Visio インスタンスの起動時にアドオンが自動的に実行されるように定義することもできます。実行可能ファイルによって実装されるアドオンに対して同様の設定を行う場合は、Visio の [スタートアップ] パスによって指定されたディレクトリの 1 つに実行可能ファイルを格納します。

VSL に実装されたアドオンのうち、Visio の起動時に実行するアドオンについては、その VAOREGSTRUCT invokeOnMask メンバに VAO_INVOKE_LAUNCH を設定する必要があります。この定数を使用すると、Visio インスタンスが起動したときに自動的に実行するアドオンと、そうでないアドオンの両方を 1 つの VSL ファイルに実装できます。

VAOREGSTRUCT は単なるデータ構造体であり、Visio インスタンスの操作を行うわけではありません。Visio インスタンスが VSL に V2LMSG_ENUMADDONS を送ると、VSL は Visio インスタンスに対して、VAOREGSTRUCT の配列へのポインタを返します。それによって、Visio インスタンスは、この配列内のデータを参照できるようになります。このとき、Lib.c は Vao.c 内に実装される以下のようなユーティリティを使用します。

result = VAOUtil_RegisterAddons(
          ((LPVAOV2LSTRUCT)lpParam)->wSessID,
          stc_myAddons,
          sizeof(stc_myAddons)/sizeof(VAOREGSTRUCT));

このコードの機能の詳細については、Vao.c の中のソース コードを参照してください。

TOP へ

アドオンの実行

Visio のインスタンスは、VSL にアドオンの実行を指示するとき、VSL に V2LMSG_RUN を送ります。実行するアドオンの序数は wParam パラメータによって渡されます。

Visio のインスタンスが V2LMSG_RUN を送るのは、指定されたアドオンが、アドオン登録用の構造体で宣言されている定数に従って、有効であると判断されたときだけです。アドオンが、有効/無効を示す定数として VAO_ENABLEDYNAMIC を使用していれば、VSL は既に Visio インスタンスからの V2LMSG_ISAOENABLED メッセージに対して VAORC_L2V_ENABLED と応答しているはずです。

Visio のインスタンスは V2LMSG_RUN で、実行するアドオンの序数のほかに、VAOV2LSTRUCT 構造体へのポインタを渡します。VAOV2LSTRUCT は Vao.h ファイルの中で次のように記述されています。

VAO_EMBEDDABLE_STRUCT
{

HINSTANCE
LPVAOFUNC
WORD
LPVOID
LPSTR

HVisInst;
lpfunc;
wSessID;
lpArgs;
lpCmdLineArgs;

//Handle of running Visio instance
//Callback address in Visio
//ID of session
//Reserved for future use
//Command line arguments

} VAOV2LSTRUCT, FAR* LPVAOV2LSTRUCT;

この構造体は、メッセージを送信している Visio インスタンスのインスタンス ハンドルを提供します。(lpfunc および lpArgs は Vao.c の中の他の関数によって使用されます)。lpCmdLineArgs には、Visio インスタンスがアドオンに渡す引数の文字列が設定されます。これは Visio インスタンスが実行可能ファイルとして実装された同種のアドオンに渡す文字列と同じです。

wSessID は、Visio インスタンスが送信した V2LMSG_RUN に関連付けられているセッションに割り当てられた ID です。たとえば、アドオンでモードレスな処理を開始するときなどに wSessID を使用します。

ほとんどのアドオンは、V2LMSG_RUN を受け取ったときにモーダルな処理を実行します。つまり、メッセージを受け取り、なんらかの処理を行ってから Visio インスタンスに制御を戻します。アドオンによって特に指定されない限り、Visio インスタンスはアドオンから制御が返された時点でセッションは終了したものとみなします。

これの一般的な擬似コードは次のとおりです。

case V2LMSG_RUN:
     wParam は実行するアドオンの序数です。
     ここで、wParam で指定されるアドオンの処理を実行します。
          たとえば、Visio のオブジェクトの初期化、そのオブジェクトに対するメソッドの呼び出し、
          およびプロパティの呼び出しなどを実行します。前のセクションで説明した C++ のサポート サービスを利用して
          このコード部分を置き換えることもできます。
     if (処理が成功した場合)
          return VAORC_SUCCESS;
     else
          return VAORC_XXX;        // vao.h を参照してください。

V2LMSG_RUN を受け取ったアドオンが処理を開始した後、その制御が Visio のインスタンスに返されても、処理が終了しない場合もあります。そのような処理をモードレスと言います。たとえば、無期限に表示されるウィンドウが、アドオンによって開かれるような場合があります。

アドオンがモードレスな処理を実装する場合、このアドオンは V2LMSG_RUN によって渡されたセッション ID を保持しておく必要があります。このようなアドオンの擬似コードは次のとおりです。

case V2LMSG_RUN:
     wParam は実行するアドオンの序数です。
     ここで、モードレスな処理の初期化を行います。
          たとえば、ウィンドウを開いて、そのウィンドウ ハンドルを変数に格納しておきます。
     if (処理が成功した場合)
          {
          lParam->wSessID を変数に格納しておきます。
          return VAORC_L2V_MODELESS;
          }
     else
          return VAORC_XXX;        // vao.h を参照してください。

処理が成功したときに VAORC_L2V_MODELESS が返されています。これは VSL が V2LMSG_RUN メッセージの処理を完了した後もセッションが継続していることを、Visio インスタンスに知らせるメッセージです。

このように開始されたモードレス セッションは、VSL がそのセッションを終了するか、そのセッションに関連づけられている Visio インスタンスが終了するまで継続します。

VSL によって開かれたウィンドウが閉じられた場合など、VSL はそのセッションの終了処理に VAOUtil_SendEndSession 関数を使用します。パラメータ wSessID には、終了するセッションの ID が設定されています。

VAOUtil_SendEndSession(wSessID);         //wSessID: 終了するセッションの ID

Visio のインスタンスの終了時には、残っているすべてのセッションに V2LMSG_KILLSESSION が送られます。Visio インスタンスは、VSL に V2LMSG_KILLSESSION と共に VAOV2LSTRUCT 構造体を渡します。VAOV2LSTRUCT wSessID には、終了するセッションの ID が指定されています。VSL はこれに対応して、指定されたセッションを終了し、必要な後処理を行います。

Top