ActiveX オートメーション

ActiveX オートメーションとは

ActiveX を用いた AutoCAD 内部の VLA オブジェクトについて見てきました。ActiveX は AutoCAD 以外の外部アプリケーションで使用されている VLA オブジェクトを使うことで、それらのアプリケーションと連動したプログラムを構築することができます。この仕組みは AutoCAD から外部アプリケーションへアクセスすることもできますが、外部アプリケーションの主に Visual Basic で書かれたプログラムから AutoCAD へアクセスできるものでもあります。ここでは、前者の AutoLISP から 外部アプリケーションにアクセスする方法を見ていきます。

Windows で広く用いられているこの技術は AutoCAD のヘルプでは ActiveX オートメーションと呼ばれています。古くは OLE オートメーション、現在では COM と言った方が一般的のようで、COMインターフェースを使って他のアプリケーションにアクセスすることを Windows では「オートメーション」と呼んでいます。

外部アプリケーションのオブジェクトを扱うには、当然ながらそのオブジェクトモデルに関する情報が必要であり、外部アプリケーションのヘルプなどを詳しく調べる必要があります。ヘルプは、通常 Visual Basic 向けに書かれています。また、連動する外部アプリケーションのバージョンなどの環境が各々ユーザーの実行環境で異なることが予想されるため、各々の環境に合わせて変更しなければならない可能性もあります。このような情報の収集と実行環境の問題から複雑な印象を受けますが、条件が整いさえすればさほど難しいものではありません。外部アプリケーションのオブジェクトモデルも、AutoCAD のオブジェクトモデルで見たのと同じコレクションとオブジェクトの木構造になっているからです。

外部アプリケーションのオブジェクトを扱う手順は、AutoCAD の VLA オブジェクトのルートが AutoCAD自身を表す Application オブジェクトであったように、外部アプリケーションの Application オブジェクトをルートとし、そこから個々の要素を VLA オブジェクトとしてアクセスしていきます。

次にその中の VLA オブジェクトのメソッドやプロパティへのアクセスですが、「タイプライブラリ」というものが使えれば、AutoCAD の VLA オブジェクトで、vla-メソッド名、vla-get-プロパティ名、vla-put-プロパティ名、と行ったのと同様の作法で行うことができます。「タイプライブラリ」はオブジェクトがどのようなメソッドやプロパティを備えているか情報を含んだファイルです。「タイプライブラリ」が使用できなければ、VLAオブジェクトのメソッドやプロパティにアクセスする一般化された関数を使います。

最後に、外部の VLA オブジェクトについては、オブジェクトの開放について配慮する必要があります。

prog-id

外部アプリケーションの Application オブジェクトは、それを表す prog-id を指定して作成します。prog-id は文字列で表されます。prog-id を調べるには、アプリケーションのヘルプなどを調べる必要があります。もともと ActiveX で連動できないアプリケーションには prog-id はありません。

prog-id の形式は、以下の形式をとります。<バージョン>は付けない場合があります。

"<アプリケーション名>.<オブジェクトタイプ>.<バージョン>"

主要なアプリケーションの prog-id は以下のとおりです。

アプリケーション prog-id
Microsoft Access "Access.Application"
Microsoft Excel "Excel.Application"
Microsoft Outlook "Outlook.Application"
Microsoft PowerPoint "PowerPoint.Application"
Microsoft Word "Word.Application"

Application オブジェクトの作成と取得

Application オブジェクトの作成は、目的のアプリケーションがデスクトップで起動してウィンドウが表示されるのとは無関係で、作成段階では基本的に Windows システム内部に Application オブジェクトが作成されるだけです。アプリケーションのウィンドウをデスクトップに表示するには、この Application オブジェクトに対して「表示」とプロパティを設定したり「開く」などのメソッドを送ったります。

AutoLISP関数
(vlax-create-object prog-id)
prog-id:文字列
Application オブジェクトを新規に VLA オブジェクトとして作成します。
戻り値:VLA オブジェクト、または nil
AutoLISP関数
(vlax-get-or-create-object prog-id)
prog-id:文字列
既存の Application オブジェクトを VLA オブジェクトとして返します。既存のものが存在しない場合は、新しい VLA オブジェクトを作成します。。
戻り値:VLA オブジェクト、または nil
AutoLISP関数
(vlax-get-object prog-id)
prog-id:文字列
既存の Application オブジェクトを返します。
戻り値:VLA オブジェクト、または nil

vlax-create-object 関数は、新規に Application オブジェクトを Windows 内に作成して返します。

vlax-get-or-create-object 関数は、既存の Application オブジェクトが Windows 内に存在した場合はそれを返し、存在しなかった場合は新規に作成して返します。まれに、既存のものが存在しているにもかかわらず、新規のオブジェクトが作成される場合があるようです。

vlax-get-object 関数は、Windows 内の既存の Application オブジェクトを返します。

prog-id 引数には、prog-id を文字列で与えます。

戻り値は、Application オブジェクトを指す VLA オブジェクトです。Application オブジェクトが何らかの原因で得られなかった場合は nil を返します。

一般的な使い方は以下のとおりです。

_$ (setq excel-1 (vlax-create-object "Excel.Application"))⏎
#<VLA-OBJECT _Application 0000000033290af8>
_$ (setq excel-2 (vlax-get-or-create-object "Excel.Application"))⏎
#<VLA-OBJECT _Application 0000000033290af8>
_$ (setq excel-3 (vlax-get-object "Excel.Application"))⏎
#<VLA-OBJECT _Application 0000000033290af8>

VLA オブジェクトの解放

外部の Application オブジェクトやその下の各種 VLA オブジェクトは解放を行わなかった場合、たとえ不要だったり無効だったりした場合でも AutoLISPシステムのメモリー管理の範囲外であり、自動的にガーベージコレクションで AutoLISP システムのメモリーから解放されることはありません。そのため外部の VLA オブジェクトに対しては AutoLISP プログラムから解放という操作をしなければなりません。この処理の実体は参照しているハンドラを無効にして、ハンドラをガーベージコレクションの対象に加える、AutoLISP システムのガーベージコレクションのために行う処理です。処理が終わって不要になったら 外部 VLA オブジェクトは解放を行ってハンドラを無効にしてください。なお、AutoCADの VLA オブジェクトに対して行った場合も、そのハンドラが無効になるだけで図形が削除されるようなものではありません。

ハンドラが無効になっても、指していた外部の VLE オブジェクトが Windows システム内部から直ちに無くなるわけではなく、その処理は Windows に任されています。このことは、外部アプリケーションの Application オブジェクトを解放しても、外部アプリケーションを Windows 上で終了させることにはならないということを意味します。この段階ではハンドラが無効になることによって単に AutoLISP システムから外部へアクセスする手掛かりがなくなるだけです。その後 Windows が不要なオブジェクトを削除します。明示的に AutoLISP から外部アプリケーションを Windows 上で終了させる手順は、外部アプリケーションに「終了」を意味するメソッドを送ります。そのうえで、AutoLISP システム内部の外部 Application オブジェクトを解放してハンドラを無効にすることになります。

AutoLISP関数
(vlax-release-object obj)
obj:VLA オブジェクト
VLA オブジェクトを解放します。
戻り値:整数

vlax-release-object 関数は、VLA オブジェクトを解放します。主に外部アプリケーションの VLA オブジェクトの解放に用います。

obj 引数には、対象の VLA オブジェクトを指定します。

戻り値は、正常に実行された場合は整数が返ります。この数値は VLE オブジェクトを参照している残りのハンドラの数を示すようです。失敗した場合はエラーが発生します。

一般的な使い方は以下の通りです。最初は excel-1 と excel-2 は同じ Application オブジェクトを指しています。途中で excel-1 に代入されていた Application オブジェクトが解放されてハンドラの内容がリセットされていますが excel-2 の状態は変わらず、こちらから外部アプリケーションにアクセスすることができます。

_$ excel-1⏎
#<VLA-OBJECT _Application 0000000033290af8>
_$ excel-2⏎
#<VLA-OBJECT _Application 0000000033290af8>
_$ (vlax-release-object excel-1) ⏎
2
_$ excel-1⏎
#<VLA-OBJECT 0000000000000000>
_$ excel-2⏎
#<VLA-OBJECT _Application 0000000033290af8>
AutoLISP関数
(vlax-object-released-p obj)
obj:VLA オブジェクト
VLA オブジェクトが解放されているかどうかを調べます。
戻り値:nil、またはnil以外

vlax-object-released-p 関数は VLA オブジェクトが解放されているかどうかを調べます。この関数の実態は単にハンドラが有効か無効かを調べるもので、ハンドラが有効であってもオブジェクトは存在しないということもありえます。外部アプリケーションと連携させている場合は、オブジェクトを取得したら直ちに利用と解放を行っておく方が安全です。

obj 引数には、対象の VLA オブジェクトを指定します。

戻り値は、解放されていれば nil 以外が、解放されていなければ nil が返ります。

使用例は以下のとおりです。

_$ excel-1⏎
#<VLA-OBJECT 0000000000000000>
_$ excel-2⏎
#<VLA-OBJECT _Application 0000000033290af8>
_$ (vlax-object-released-p excel-1) ⏎
T
_$ (vlax-object-released-p excel-2) ⏎
nil