ActiveX で追加となる基本事項

LISP とオブジェクト指向

ActiveX 対応関数を使う上での、VLA オブジェクトとバリアント型やセーフ配列の道具がそろいました。ここでは、VLA オブジェクトを使う上で浮上してくる LISP におけるオブジェクト指向の記述方法について触れます。

一般的なオブジェクト指向言語の記述で、メソッドの呼び出しは次のようなものです。

オブジェクト.メソッド名(引数, 引数,…)

これを LISP においては、次のように書き表します。メソッド名が関数名となり、その第一引数に VLA オブジェクトを指定します。その際、メソッド名の頭には「vla-」を付加した関数名とします。

(vla-メソッド名 VLAオブジェクト 引数 引数…)

また、一般的なオブジェクト指向言語におけるプロパティへのアクセスは次のようなものです。

オブジェクト.プロパティ名 = 値

AutoLISP では、プロパティ名が関数名の一部となります。関数名は、値を取り出す場合は「vla-get-」を、値をセットする場合は「vla-put-」を、プロパティの頭に付加した関数名にします。メソッドの場合と同様にその第一引数にVLAオブジェクトを指定します。値をセットする場合は、続けてその値を引数で渡します。

(vla-put-プロパティ名 VLAオブジェクト 値)

このように、一般的なオブジェクト指向言語の記述の順番は異なりますが、同じことを LISP でも表現可能です。また、LISP の関数は、引数のコピーが作られ、決して元の変数の値には影響を及ぼさないものでした。しかし、VLA オブジェクトはオブジェクトそのものではなく、ハンドルです。メソッドやプロパティの変更で、オブジェクトの状態は変化し副作用が発生します。

オブジェクト情報

ActiveX 対応関数は、実にさまざまなものが用意されています、これらをすべて説明することは不可能です。一つ一つは、やりたいことに応じて AutoCAD のヘルプファイルを検索して、必要な情報を見つけていく必要があります。

古い AutoCAD のヘルプは、ActiveX についての記述が含まれていない場合があります。その場合は別途用意されている Visual Basic のヘルプから情報が得られます。このヘルプは、AutoCAD 2011 の場合は通常次の場所にインストールされています。

C:\Program Files\Common Files\Autodesk Shared\acadauto.chm
visual basic acadauto

しかし、AutoCAD のヘルプはオンラインで公開されていますので、そちらの新しいバージョンのヘルプファイルを参照した方が、現在は手軽でしょう。

ヘルプを検索するためには、「vla-」や「vla-get-」、「vla-put-」を除いたメソッド名やプロパティ名で検索する必要があります。しかし最初は、そもそもどのようなオブジェクトがあって、どのようなメソッド名やプロパティ名となっているか判りません。そのため、まず目的の図形などから、どのようなオブジェクトで、どのようなメソッドやプロパティがあるかを調べます。具体的には、AutoCAD で目的の図形を作成して、その図形のオブジェクトとしての情報を表示させます。

AutoLISP関数
(vlax-dump-object obj [method])
obj:VLAオブジェクト
method:nil、またはnil以外
VLAオブジェクトのプロパティとメソッドを一覧表示します。
戻り値:nil以外

vlax-dump-object 関数は、VLA オブジェクトのプロパティとメソッドの一覧を表示します。プロパティは値も表示されます。AutoCAD の VLA オブジェクトを扱っている場合は大丈夫ですが、後述の ActiveX オートメーションで外部アプリケーションの VLA オブジェクトに対しては、エラーが発生して AutoCAD が操作不能になる場合があります。

obj 引数には、調べる VLA オブジェクトを指定します。

method 引数は省略可能ですが、省略またはnilの時はプロパティのみ表示されます。nil 以外が指定された場合は、プロパティとメソッドが表示されます。

戻り値は、関数が成功すれば nil 以外を返します。VLA オブジェクトが無効な場合など、関数が失敗した場合はエラーが発生します。

次は、円弧の VLA オブジェクトのプロパティとメソッドを表示した例です。arc 変数には、円弧の VLA オブジェクトが代入されています。

_$ (vlax-dump-object arc T) ⏎
; IAcadArc2: AutoCAD Arc インタフェース
; プロパティの値:
; Application (RO) = #<VLA-OBJECT IAcadApplication 0000000140c59e48>
; ArcLength (RO) = 157.08
; Area (RO) = 2853.98
; Center = (0.0 0.0 0.0)
; Document (RO) = #<VLA-OBJECT IAcadDocument 00000000333a0fc0>
; EndAngle = 1.5708
; EndPoint (RO) = (6.12323e-015 100.0 0.0)
; EntityTransparency = "ByLayer"
; Handle (RO) = "2A7"
; HasExtensionDictionary (RO) = 0
; Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 0000000033227cf8>
; Layer = "0"
; Linetype = "BYLAYER"
; LinetypeScale = 1.0
; Lineweight = -1
; Material = "ByLayer"
; Normal = (0.0 0.0 1.0)
; ObjectID (RO) = 309
; ObjectID32 (RO) = 309
; ObjectName (RO) = "AcDbArc"
; OwnerID (RO) = 308
; OwnerID32 (RO) = 308
; PlotStyleName = "ByLayer"
; Radius = 100.0
; StartAngle = 0.0
; StartPoint (RO) = (100.0 0.0 0.0)
; Thickness = 0.0
; TotalAngle (RO) = 1.5708
; TrueColor = #<VLA-OBJECT IAcadAcCmColor 0000000033227e70>
; Visible = -1
; サポートされているメソッド:
; ArrayPolar (3)
; ArrayRectangular (6)
; Copy ()
; Delete ()
; GetBoundingBox (2)
; GetExtensionDictionary ()
; GetXData (3)
; Highlight (1)
; IntersectWith (2)
; Mirror (2)
; Mirror3D (3)
; Move (2)
; Offset (1)
; Rotate (2)
; Rotate3D (3)
; ScaleEntity (2)
; SetXData (2)
; TransformBy (1)
; Update ()
T

プロパティの (RO) は読み込み専用を表します。また、Boolean 型のプロパティは、真が -1、偽が 0 と表示されます。

メソッドのカッコ内の数字は関数の引数の数を表しています。ただし、この引数の数は AutoLISP の記法では必ず第一引数が VLA オブジェクトでしたが、その数は含まれていません。

次のような関数を用意しておくことによって、簡単に作図ウィンドウから図形を選んで【コンソール】にプロパティを表示させることができます。

(defun dumpObj () (vlax-dump-object (vlax-ename->vla-object (car (entsel)))))

また、プロパティについては、VisualLISP の【検査】ウィンドウを使って表示することもできます。、エディタや【コンソール】で調べたい VLA オブジェクトを格納した変数を選択して【検査】ボタンやメニューを選ぶと、【検査】ウィンドウが開きます。VisualLISP では、【検査】する対象が VLA オブジェクトだった場合、オブジェクトのプロパティを表示します。

visual lisp inspect
AutoLISP関数
(vlax-property-available-p obj property [check-modify])
obj:VLAオブジェクト
property:シンボルまたは文字列
check-modify:nil、またはnil以外
VLAオブジェクトが、特定のプロパティを持っているかどうかを調べます。
戻り値:nil、またはnil以外

vlax-property-available-p 関数は、オブジェクトが特定のプロパティを持っているかどうかを調べます。

obj 引数には、調べる VLA オブジェクトを指定します。

property 引数は、調べるプロパティ名をシンボルか文字列の形で渡します。文字列の場合でも、大文字小文字は区別されません。

check-modify 引数に nil 以外を指定すると、プロパティが存在し、かつ読み書き可能かを調べます。

戻り値は、プロパティが存在していれば nil 以外が、プロパティが存在しないか読み込み専用であれば nil を返します。

次の例では、arc 変数に円弧の VLA オブジェクトが代入されています。

_$ (vlax-property-available-p arc 'Center) ⏎      ; 中心
T
_$ (vlax-property-available-p arc "Center")⏎      ; 中心(文字列)
T
_$ (vlax-property-available-p arc 'Diameter) ⏎    ; 直径
nil
_$ (vlax-property-available-p arc 'Area) ⏎        ; 面積
T
_$ (vlax-property-available-p arc 'Area T) ⏎      ; 面積(読み取り専用)
nil
AutoLISP関数
(vlax-method-applicable-p obj method)
obj:VLAオブジェクト
method:シンボルまたは文字列
VLAオブジェクトが、特定のメソッドをサポートしているかどうか調べます。
戻り値:nil、またはnil以外

vlax-method-applicable-p 関数は、オブジェクトが特定のメソッドを持っているかどうかを調べます。

obj 引数には、調べる VLA オブジェクトを指定します。

method 引数は、調べるメソッド名をシンボルか文字列の形で渡します。文字列の場合でも、大文字小文字は区別されません。

戻り値は、メソッドが存在していれば nil 以外が、存在しない場合は nil を返します。

次の例では、arc 変数に円弧の VLA オブジェクトが代入されています。

_$ (vlax-method-applicable-p arc 'Copy) ⏎
T
_$ (vlax-method-applicable-p arc 'AddFitPoint) ⏎
nil