Professional Documents
Culture Documents
10 在AutoLISP中使用ActiveX对象
10 在AutoLISP中使用ActiveX对象
10 在AutoLISP中使用ActiveX对象
下一级对象也是其上级对象的属性。
AutoCAD 通过集合将所有对象进行分类,例如,块集合是
由 AutoCAD 图形中的所有块定义组成的,而模型空间集合则包
括模型空间中的所有的图形对象(圆、直线、多义线等)。
10.2.1 访问 AutoCAD 应用程序
1. 获取 AutoCAD 应用程序
(setq myacad(vlax-get-acad-object))
; Quit ()
; RunMacro (1)
; UnloadArx (1)
; UnloadDVB (1)
; Update ()
; ZoomAll ()
在 Property values (属性)部份列出了 AutoCAD 应用程序具有
ActiveDocument ( 活动的文档 ) 、 Application ( 应用程序的指针 )
、 Caption (标题)、 FullName (可执行文件名)等属性。
其中标记为 #<VLA-OBJECT … > 的属性是 VLA 对象。例如, Act
iveDocument (活动的文档)、 Documents (一般文档)、 MenuBar (
菜单条 ) 、 MenuGroups ( 菜单组 ) 和 Preferences ( 设置 ) 这
些对象属于 VLA 对象 , 它们可以被继续访问 , 引出下一级 ActiveX
对象,了解它们的属性和方法。
带有标记 (RO) 的属性是只读的,不能被修改 ,例如属性 Caption
(RO) = "AutoCAD 2006 – [Drawing1.dwg]" ,表示 AutoCAD 应用
程序的标题是 "AutoCAD 2006 – [Drawing1.dwg]" ,它是只读的,
不能被修改。
在 Methods supported ( 支持的方法 ) 部份列出了可以对过
AutoCAD 应用程序施加 Eval 、 GetAcadState 、 GetInterface O
bject 等操作。
10.2.2 访问其他 AutoCAD 对象
获取 AutoCAD 应用程序这个根对象之后 , 沿着 AutoCAD 对象模
型图,就可以将其作为起点,逐级访问它的下一级 VLA 对象。
获取 AutoCAD 应用程序之外的对象 , 是一个前缀为 vla-get- 的
函数,格式如下:
( vla-get-property object )
参数 object 必须是 VLA 对象, property 是 object 的 VLA 对象
类型的属性。该属性可通过 vlax-dump-object 函数获得。
假定本作业依次绘制了一条起点为 (10,20) 终点为 (60,20) 的
直线和圆心为 (35,20) 半径为 25 的一个圆。按照以下步骤,可以
沿着 AutoCAD 对象模型图所示的 AutoCAD 应用程序活动文档
模型空间图形对象的顺序,访问这条直线和这个圆。
1. 获取 AutoCAD 应用程序对象
2. 了解 AutoCAD 应用程序的属性
3. 获取活动文档程序对象
(setq mydoc(vla-get-ActiveDocument myacad)); 返回活动文
档的指针 #<VLA-OBJECT IAcadDocument 01165340> ,将其赋给变量 mydoc
。
4. 了解活动文档的属性
(vlax-dump-object mydoc)
返回的属性信息中有以下一行:
;ModelSpace (RO) = #<VLA-OBJECT IAcadModelSpace 011c1e04> 。 ModelSp
ace 是活动文档的属性之一,也是活动文档的下一级 VLA 对象。
5. 获取模型空间对象
(setq myms(vla-get-ModelSpace mydoc))
返回模型空间的指针 #<VLA-OBJECT IAcadModelSpace 011c1e04> ,将其赋给
变量 myms 。
6. 了解活动文档的属性和方法
(vlax-dump-object myms t)
返回的属性信息中有以下一行:
; Count (RO) = 2 。说明该模型空间当前有两个图形对象。
返回的方法信息中有 Add3Dface 、 Add3Dmesh 、 Add3Dpoly 、 AddArc 、 AddA
ttribute 、 AddBox 、 AddCircle 、…、 Item 等许多方法。
其中 Item 是根据序号获取图形对象,第一个图形对象的序号为 0 。
7. 获取模型空间的第一个图形对象
(setq myline(vla-item myms 0))
返回第一个图形对象 , 即这条直线的指针 #<VLA-OBJECT IAcadL
ine 011b9e74> ,将其赋给变量 myline 。
8. 了解这条直线的属性和方法
(vlax-dump-object myline t)
返回有关这条直线属性的信息如下:
; Property values:
; Angle (RO) = 0.0
; Application (RO) = #<VLA-OBJECT IAcadApplication 00b5e51c>
; Delta (RO) = (50.0 0.0 0.0)
; Document (RO) = #<VLA-OBJECT IAcadDocument 01165340>
; EndPoint = (60.0 20.0 0.0)
; Handle (RO) = "81"
; HasExtensionDictionary (RO) = 0
; Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 040a53f4>
; Layer = "0"
; Length (RO) = 50.0
; Linetype = "ByLayer"
; LinetypeScale = 1.0
; Lineweight = -1
; Normal = (0.0 0.0 1.0)
; ObjectID (RO) = 2129985160
; ObjectName (RO) = "AcDbLine"
; OwnerID (RO) = 2129984760
; PlotStyleName = "ByLayer"
; StartPoint = (10.0 20.0 0.0)
; Thickness = 0.0
; TrueColor = #<VLA-OBJECT IAcadAcCmColor 040a6db0>
; Visible = -1
从以上有关这条直线属性的信息中 ,可以了解到这条直线与 X
轴正方向夹角为 0 、三个坐标的增量分别是 (50.0 0.0 0.0) 、
终点坐标是 (60.0 20.0 0.0) 、句柄是 "81" 、所在图层的名字
是 "0" 、长度为 50.0 、线型名是 "ByLayer" 、线型比例为 1.0
、线宽为 -1 ( 默认 ) 、厚度方向为 (0.0 0.0 1.0) 、打印样式名
是 "ByLayer" 、起点坐标是 (10.0 20.0 0.0) 、厚度为 0.0 。
返回这条直线的有关方法的信息如下:
; Methods supported:
; 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 ()
从以上有关这个圆有关方法的信息中,可以了解到对这个圆可以
10. 了解这个圆的属性和方法
(vlax-dump-object mycircle t)
返回有关这个圆的属性信息中大部分与直线相同,不同的部份
有 Area ( 面积 ) = 1963.5 、 Center ( 圆心 ) = (35.0 20.0 0.0)
、 Circumference (周长) = 157.08 、 Diameter (直径) = 50.0 和
Radius (半径) = 25.0 。
返回有关这个圆的方法信息中与直线完全相同。
10.2.3 使用检验工具了解 AutoCAD 对象的属性
1. 获取 AutoCAD 应用程序对象
图 10-3 活动文档的检验窗口
4. 了解模型空间的属性
双击活动文档的检验窗口的 ModelSpace 属性,将弹出图 10
-4 所示模型空间检验窗口。在该窗口可以看到属性 Count 的值
为 2 ,说明在模型空间当前有两个图形对象。
图 10-4 模型空间检验窗口
5. 了解直线的属性
以上表达式获取了这个圆的
对象的指针,并将其赋给了 myci
rcle 变量。选取 mycircle ,然
后单击按钮 ,将弹出图
10-6 所示这个圆的检验窗口。
不难看出,用检验窗口显
示有关 VLA 对象的属性,与 10.2
.1 节通过 vlax-dump-object 函
数显示有关 VLA 对象的属性基本 图 10-6 圆的检验窗口
10.2.4 通过 Help 功能了解 AutoCAD 对象
① 在 VLISP 环境下,按功能键 F1 ;
录选项卡内双击 ;
③ 在展开的目录树上双击 ;
- 7 所示有关直线对象方法和属性的信息。
图 10 - 7 有关直线对象方法和属性的帮助信息
以上帮助信息告诉用户创建一条直线用 Addline 方法,编辑直
线用第一列显示的各种方法,第二列显示了直线的全部属性。
至此已介绍了了解 AutoCAD 对象的属性通过帮助功能显示的
不难看出,用检验窗口显示有关 VLA 对象的属性,与 10.2 节通过 v
lax-dump-object 函数显示有关 VLA 对象的属性基本相同。
RetVal = object.AddLine(StartPoint,EndPoint)
(vlax-make-variant [ 值 ] [ 类型 ])
该函数返回的值为所创建的变体。
类型 值 含义
Vlax-vbEmpty 预定义的变体 0 未初始化(默认值)
Vlax-vbNull 1 空数据
Vlax-vbInteger 2 整数型
Vlax-vbLong 3 长整数型
Vlax-vbSingle 4 单精度浮点数
Vlax-vbDouble 5 双精度浮点数
Vlax-vbString 8 字符串
Vlax-vbObject 9 对象
Vlax-vbBoolean 11 布尔值
Vlax-vbArray 8192 数组
表 10-3 LISP 数据类型与默认的 ActiveX 数据类型对照表
检查 varintstr 的值:
_$ (vlax-variant-value varintStr) ; 返回 "5"
这说明 varintstr 中确实包含字符串。
2. 安全数组
在 VLISP 中,有可能与一些强制数据类型的编译型应用程序进行数据交换
,而这样的程序不可能直接接受 AutoLISP 特有的表的数据类型,比如 Activ
eX ,为了解决这个矛盾, VLISP 设立了安全数组这一数据类型。
安全数组是一种特殊的数组。它限制了不能在数组的边界之外赋值,因此
不会引起数据异常,所以这类数组是安全的。
( 1 )创建安全数组
创建安全数组用 vlax-make-safearray 函数,调用的格式如下:
该函数要求至少有两个参数,第一个参数是确定该数组中元素的数据类型 ,
可确定的数据类型及其预定义的数据类型如表 10-4 所示。
表 10-4 可作为安全数组的预定义的数据类型
预定义的变体类型 值 含 义
vlax-vbInteger 2 整数
Vlax-vbLong 3 长整数
Vlax-vbSingle 4 单精度浮点数
Vlax-vbDouble 5 双精度浮点数
Vlax-vbString 8 字符串
Vlax-vbObject 9 对象
Vlax-vbBoolean 11 布尔类型
Vlax-vbVariant 12 变体
由于它们的值在 AutoCAD 以后的版本中可能会作修改,所以应该使用预定义
的常量,而不要直接使用常量所对应的数值。
返回值为创建的安全数组。
以下是一些创建安全数组的表达式:
表 10-5 新创建的数组中的元素初始化方式
数据类型 初始值
数值 0
字符串 零长度字符串。
布尔值 vlax-false
对象 nil
变体 未初始化 (vlax-vbEmpty)
( 2 )为整个安全数组赋值
参数变量必须是安全数组类型的变量,数值表是数值类型的表,
表的长度必须等于数组元素的个数。该函数返回 #<safearray.
..> 。
对于多维数组,数值表必须为表的列表,其中每个表对应于数组
中的一维。例如已创建了一个名字为 mt2 的二维字符串数组,第
一维下限为 0 ,上限为 1 ,包括两个元素,第二维下限为 1 ,上限为
3 包括三个元素。用 vlax-safearray-fill 函数填满该数组:
(vlax-safearray-fill mt2 '(("a" "b" "c") ("d" "e" "f")
)) ; 返回 #<safearray...>
( 3 )列出安全数组的内容
列出安全数组的内容用 vlax-safearray->list 函数,调用的格式如下:
(vlax-safearray->list 安全数组 ) 例如
(vlax-safearray->list p1) ; 返回 (1.0 2.0 3.0)
(vlax-safearray->list mt2) ; 返回 (("a" "b" "c") ("d" "e" "f"))
( 4 )为安全数组内指定的元素赋值
为安全数组内指定的元素赋值用 vlax-safearray-put-element 函数 , 调用
的格式如下:
(vlax-safearray-put-element 变量 索引 ...)
参数变量的类型为 SafeArray 的变量;对于一维数组,应指定一个索引值,对
于二维数组,应指定两个索引值,依此类推;值是赋给安全数组内指定的元素元
素的值;返回指定给数组元素的值。
例如,已创建了名字为 p1 的由双精度数据构成的一维数组,数组的下界为 0 ,上
界为 2 。用 vlax-safearray-put-element 填满该数组:
(vlax-safearray-put-element p1 0 10) ;返回 10 ,将数组 p1 的第 1 个元
素赋值为 10(vlax-safearray-put-element p1 1 20) ;返回 20 ,将数组 p1
的第 2 个元素赋值为 20(vlax-safearray-put-element p1 2 30) ;返回 30
,将数组 p1 的第 3 个元素赋值为 30 调用 vlax-safearray->list 函数确认
p1 的内容:返回 (10.0 20.0 30.0) 对于二维数组,应指定两个索引值。例如
已创建了名字为 mt2 的由字符串构成的二维数组,第一维下限为 0 ,上限为 1 ,
包括两个元素,第二维下限为 1 ,上限为 3 包括三个元素。
每个维的下界为 1 ,上界为 2 。用 vlax-safearray-put-element 填满该数组:
(vlax-safearray-put-element mt2 0 1 "a1") ;返回 "a1"
(vlax-safearray-put-element mt2 0 2 "b2") ;返回 "b2"
(vlax-safearray-put-element mt2 0 3 "c3") ;返回 "c3"
(vlax-safearray-put-element mt2 1 1 "d4") ;返回 "d4"
(vlax-safearray-put-element mt2 1 2 "e5") ;返回 "e5"
(vlax-safearray-put-element mt2 1 3 "f6") ;返回 "f6"
调用 vlax-safearray->list 函数确认 mt2 的内容:
(vlax-safearray->list mt2) ;返回 (("a1" "b2" "c3") ("d4" "e5" "f6"))
( 5 )在变体中使用安全数组
安全数组的数据必须用变体传给 ActiveX 。如果需要为一个数
组创建一个变体 ,就必须先创建数组再转换成变体。例如创建一
个包含 5 个双精度实数数组的变体的步骤如下:
① 给数组分配空间
(setq a5(vlax-make-safearray vlax-vbDouble '(0 . 4)))
② 给数组赋值
(vlax-safearray-fill a5 '(1.1 2.2 3.3 4.4 5.5))
③ 将数组存储到变体
(setq vara5 (vlax-make-variant a5)) ;返回 #<variant 8197 ..
.>
获取该圆的颜色:
(vlax-get-property circ 'Color) ;返回 256
10.4.2 修改图形对象的属性
假定以 (100 80) 为圆心,以 50 为半径绘制了一个圆,并
且将获取这个圆的 VLA 对象赋给了变量 circ 。可以用以下两
种函数获取图形对象的属性。
1. 用带有 vla-put- 前缀的函数,这类函数的调用语法如下
:
(vla-put-property VLA 图形对象 新的属性值 )
该类函数的名字是由 vla-put- 和 property 合成的。 prop
erty 为符号或字符串,标识要修改的属性。返回 VLA 图形对
象指定的属性。例如修改一个圆的半径时, property 就是改
为具体的属性 radius , 20 可作为半径这个属性的新值。
例如修改该圆的半径:
(vla-put-radius circ 20) ;返回 nil, 该圆的位置不变,半径改
修改该圆的面积:
(vla-put-area circ 1000) ;返回 nil, 该圆的位置不变
,面积改变为 1000 。
修改该圆的圆心:
(vla-put-center circ (vlax-3d-point '(150 50 0))) ;
返回 nil, 该圆的位置改变为 (150 50 0)
函数 vlax-put-property 的调用格式如下:
参数 property 为符号或字符串,标识要修改的属性。
例如,修改该圆的半径:
修改该圆的面积:
修改该圆的颜色:
也可以用预定义的常量来修改对象的属性。例如,如果要将
圆的填充颜色设为红色,可以用常量 acRed 代替颜色号 1 。
VLISP 提供了下列函数,可用来在操作某对象前,先测试一下是否可访
问该对象。
vlax-read-enabled-p 测试是否可读该对象。
vlax-write-enabled-p 测试是否可修改该对象的属性。
vlax-erased-p 测试该对象是否已被删除,因为被删除的对象可能
仍保留在图形数据库中。
(1) 确定该直线是否可读
(2) 确定该直线是否可被修改
(3) 确定该直线是否已被删除
(vlax-erased-p myline) ;返回 nil ,说明未被删除
图 10-10 GetBo
undingBox 方
法的定义
从图 10-10 可以看到,用 GetBoundingBox 方法可以获取图形
对象边界框的左下角点 MinPoint 和右上角点 MaxPoint 。这两个
点是在 WCS 下的三维坐标。
( 1 )获取该圆的实体名
( 2 )将该圆转换为 VLA 对象
vla-getboundingbox 函数将该圆边界框的左下角点和右上角
点的坐标存放在变量 minpoint 和 maxpoint 变量。这两个变量
,是含有三个双精度实数的安全数组的类型。
( 4 )用函数 vlax-safearray->list 查看 minpoint 和 maxpoin
t 的值
(setq p1(vlax-safearray->list minpoint)) ;返回 (150.0 3.0
0.0)
2. 判断某对象是否具有某属性
通过函数 vlax-property-available-p 可以判断某对象是否
具有某属性。该函数的调用格式如下:
(vlax-property-available-p VLA 对象 property [check-mod
ify)
参数 property 为符号或字符串,指定要检查的属性。如果指定参数 check-m
odify 的值为 T ,该函数还检查 VLA 对象的指定属性是否可被修改。只要 VLA
对象具有指定属性,该函数就返回 T ,否则返回返回 nil 。如果指定 check-mod
ify 参数的值为 T ,而该属性不可用或该属性不能修改,该函数返回 nil 。
例如,下列表达式测试 Color 和 Center 是否是 myline 具有的属性:
(vlax-property-available-p myline "Color") ;返回 T
(vlax-property-available-p myline "Center") ;返回 nil
假定 myCircle 是直线一个圆的 VLA 对象,如果调用该函数时不提供可选
参数 "T" ,测试圆的 Area 属性:
(vlax-property-available-p myCircle "area") ;返回 T ,说明圆具有 area
属性
如果要对集合中的每一个对象用一系列函数求值,可使用 vl
ax-for 函数,该函数遍历整个对象集,对每个表达式进行求值
。其调用格式如下:
(setq colorList
)
(if colorList
(progn
(setq colorList (vl-sort colorList '(lambda (lst1 lst2) (< (
car lst1) (car lst2)))))
(princ "\nColorList = ")
(princ colorList)
(foreach subList colorList
(princ "\nColor ")
(princ (car subList))
(princ " is found in ")
(princ (setq count (cdr subList)))
(princ " object")
(princ (if (= count 1)
".“
"s.")))))
(princ)
)
假定当前图形含有 12 个实体,其中两条直线和 4 个圆是在颜
色为红色和黄色时绘制的,其余 6 个实体是在颜色为随层时绘制
的 , 在控制台键入 (show-Color-Statistics) 之后,显示了以下
信息:
ColorList = ((1 . 2) (2 . 4) (256 . 6))
Color 1 is found in 2 objects.
Color 2 is found in 4 objects.
Color 256 is found in 6 objects.
10.8.3 获取集合中的成员对象
用 item 方法可以从集合中获取其成员对象。集合的 count
属性则显示集合内对象的数量。利用 item 方法和 count 属性,
可以单个地处理集合中的每个对象。
1. 获取模型空间的图形对象
函数 vla-get-count 获取模型空间图形对象的数量。调用格式
如下:
函数 vla-item 获取模型空间指定序号的图形对象。调用格式
如下:
(princ)
2. 用 ActiveX 方法定义将选到的圆改变为指定面积的命令。
用 ActiveX 方法修改图形对象的步骤是:① 获取图形对象的图元名。②
将图元名转换为 VLA 对象。③ 更新图形对象指定的属性。
(vl-load-com)
(setq ec(car (entsel "\n 选择一个圆 :"))); 获取圆的图元名
(princ)