AutoLisp学习笔记

【前言】

最近发现,做CAD二次开发的,要么是计算机相关专业的,没有CAD基础;要么是工程制图出身,不会编程。所以写了这篇博客,AutoLisp学习笔记,根据我的学习经验,旨在给没有基础的你指明学习的方向,让读者少走弯路。

AutoLISP语言是开发AutoCAD的主要工具,是LISP语言和AutoCAD有机结合的产物,在AutoCAD的发展及壮大过程中起到了重要的作用。CAD二次开发可以使用VB、LISP和C#语言,CAD均为各种方式开发了平台。之所以使用LISP,是因为经过多年的累积,已经有很多的基础代码,方便程序的开发。

掌握AutoLISP开发,需要准备如下知识:1、LISP语言 2.AutoCAD基础 3.AutoLISP函数 4.AutoLisp进阶。

一. LISP语言相关知识

跟我们学过的C++ Java语言有很大的不同,LISP语言是解释性语言,只有两个基本单位:原子(atom)和列表(List)。这里推荐如下两个博客,前者是一个常用的LISP语言的开发环境,后者是语法学习,配合使用快速学习。这样,半天的时间可以对LISP语言有初步的概念。递归是LISP的精髓,如果看懂链接博客中的所有示例,那么可以进行下一步了。

【Lisp语言: 在Windows下搭建CLisp环境】

http://blog.csdn.net/keyboardota/article/details/8237185

【Lisp入门】

http://www.cnblogs.com/suiqirui19872005/archive/2007/12/05/984517.html


二.AutoCAD基础

AutoCAD博大精深,对于我们这些开发人员,只需了解些基本操作和概念就足够了。个人认为如下几个概念比较重要,部分可以在AutoCAD术语帮助中找到。

   1、命令。

CAD的操作几乎都可以用命令描述,如创建一个以原点为圆心,半径为100的圆,可用如下几种命令形式完成。CAD中不区分大小写。

(1)CAD命令 

  命令:circle/c   

在命令栏里键入c,然后就可以用鼠标在绘图窗口中操作指定圆心和半径。

(2) AutoLisp命令


   
   
  1. _$ (setq center ‘(<span class="hljs-number"><span class="hljs-number">0</span></span> <span class="hljs-number"><span class="hljs-number">0</span></span> <span class="hljs-number"><span class="hljs-number">0</span></span>))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (command “circle” center 100)

 
  

(注:_$ 是Visual Lisp控制台的前置符,启动Visual Lisp的CAD命令是VLIDE,在控制台和CAD命令栏均可使用AutoLisp命令及ActiveX方法。在CAD命令栏查看变量前面加感叹号!)

学习过前面LISP语言后,应该可以理解setq,command命令其实是AutoLisp函数,即AutoCAD提供给开发人员的Lisp函数。前者为变量设置值,后者是AutoLisp与AutoCAD的接口,可以向AutoCAD命令行直接发送命令和参数。其中列表 ‘(0 0 0)和原子 100分别为圆心和半径的参数。如上命令括号不能省略,表示其为函数。

(3)Active X方法


   
   
  1. _$ (vl-<span class="hljs-keyword"><span class="hljs-keyword">load</span></span>-com)</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">_$ (setq acad_obj (vlax- get-acad- object))
  2. _$ (setq acad_document (vla-<span class="hljs-keyword"><span class="hljs-keyword">get</span></span>-activedocument acad_obj))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">_$ (setq m_space (vla- get-modelspace acad_document))
  3. _$ (vla-addcircle m_space (vlax -3d-point ‘( 0 0 0)) 100)

Active X技术通过将AutoCAD的对象显示在外部使用户以各种编程的方式访问AutoCAD对象。Active X函数 (vla-) (vlax-)提供了访问对象的各种方法。这里只是引入,说明了CAD命令,AutoLisp命令和ActiveX方法均能对CAD进行操作。

 2、图层。

    一组具有一定逻辑关系的数据,类似于覆盖在图形上的透明硫酸纸。可以单独查看每个图层,也可以同时查看多个图层。与PS中图层的概念一样,一个绘图可由多个叠加的图层组成,不同的图元可以选择绘制在哪个图层上。通过layer命令(CAD命令)可以生成或者选择图层。

 3、选择集。

    顾名思义,选择集就是选择的集合,在绘图窗口中,点击鼠标左键拖动鼠标,所选择的图元构成选择集。在AutoLisp 中可以用 ssget 函数对选择进行处理和过滤,得到自己想要到集合。

  4. 图元对象属性及DXF组代码

图元,顾名思义,就是CAD中最小的操作单位,如上面画的一个圆,还可以是插入的块。在CAD中,每个图元其实就是一个对象,它们具有各种属性,比如前面画的circle属性包括实体名,实体类型,辅助实体名,所在图层名,圆心坐标,半径等。这些属性都是用DXF组代码的形式写入的。组代码使用LISP语言的点对结构表示图元对象的属性,类似于C++中map结构。可用entget函数查看。


   
   
  1. _$ (command “circle” ‘(<span class="hljs-number"><span class="hljs-number">10</span></span> <span class="hljs-number"><span class="hljs-number">286.611</span></span> <span class="hljs-number"><span class="hljs-number">50.8336</span></span> <span class="hljs-number"><span class="hljs-number">0</span></span>.<span class="hljs-number"><span class="hljs-number">0</span></span>) <span class="hljs-number"><span class="hljs-number">100</span></span>)</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (setq ent1 (entlast))
  2. _$ (entget ent1)
其中, entlast 函数返回最后的图元,上述返回结果如下:


   
   
  1. (( -1 . <图元名: 7ffff705c20>) ;实体名
  2. ( 0 . "CIRCLE") ;实体类型
  3. ( 330 . <图元名: 7ffff7039f0>) ;辅助实体名
  4. ( 5 . "23A") ;实体标号
  5. ( 100 . "AcDbEntity") ;实体子类说明
  6. ( 67 . 0) ;空间类型说明
  7. ( 410 . "Model") ;空间名
  8. ( 8 . "0") ;图层名
  9. ( 100 . "AcDbCircle") ;
  10. ( 10 286.611 50.8336 0.0) ;圆心坐标
  11. ( 100.000) ;半径
  12. ( 210 0.0 0.0 1.0)) ; 3D延伸方向


更多关于DXF可参考AutoCAD的帮助。如果想得到该图元的圆心坐标,使用如下代码。


   
   
  1. _$ (cdr (assoc 10 (entget ent1)))
  2. ( 286.611 50.8336 0. 0)
※拓展:也可以用 ActiveX 的方法进行访问。


   
   
  1. _$ (setq myobject (vlax-ename-&gt;vla-<span class="hljs-keyword"><span class="hljs-keyword">object</span></span> (entlast)))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> #&lt;VLA-<span class="hljs-keyword"><span class="hljs-keyword">OBJECT</span></span> IAcadCircle <span class="hljs-number"><span class="hljs-number">0000000037</span></span>be66f8&gt;</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">_$ (vlax-safearray->list (vlax-variant-value (vlax-get- property myobject 'center)))
  2. (286.611 50.8336 0.0)
这里涉及到 ActiveX 方法和函数,看不懂可先跳过,有概念即可。

5. 块。

表示结合起来以创建单一对象的一个或多个对象。常用于块定义或块参照。在块编辑窗口中可增加其属性,在AutoLisp中使用entnext遍历属性。

6.AutoCAD的自定义配置

AutoCAD强大的平台可以使用户自定义工作区间,包括菜单,面板,双击动作等等,还能定义新的命令,可以说,AutoCAD的灵活和个性化是软件的精髓,是AutoDesk公司屹立不倒的根基。

敲击CAD命令:cui,或者【工具】->【自定义】->【界面】

这里可以自定义用户界面,比如想添加一个查看图元属性的菜单选项,可以按如下步骤:

(1)创建自定义命令 点击命令列表中的五角星,这里使用默认名称“命令1”

(2)编辑自定义命令的宏,其中^C^C表示连按两下Esc,保证退出其他命令。键入命令:

^C^C(entget (SSNAME (SSGET) 0))</span>
   
   
(3)打开菜单栏,在文件菜单中,将命令列表的“命令 1 ”拖动进去。点击确定退出。


图表 1 CAD自定义界面

(4)单击选中窗口中任一图元,然后再文件菜单中点击“命令1”,发现命令栏里返回图元的属性信息。

7.AutoCAD支持文件配置

 类似于Java的环境配置,是程序寻找文件的目录列表。

三.AutoLisp函数

参考任一一本关于AutoLisp的书均可。推荐下《AutoCAD 2008 Visual LISP二次开发入门到精通》,现已绝版(⊙﹏⊙b汗)。AutoLisp函数是二次开发的基础,基本函数不多,是Lisp语言在AutoCAD环境下的扩展,容易掌握。

四.Visual Lisp集成开发环境

CAD命令栏键入 VLIDE 命令弹出VisualLisp开发环境,包括编译器,调试器和其他工具,提高编程效率。控制台窗口可以像AutoCAD命令行那样输入AutoLisp命令,还可以输入Visual LISP命令。

五.AutoLisp进阶

 1.使用ActiveX对象

我们可以把整个AutoCAD理解为一个对象的模型,包括样式设置对象,组织结构对象,图形显示对象,图元对象,AutoCAD本身也是一个对象。这些对象根据包含关系组成了层次结构,称为对象模型。既然为对象,那么就有属性值和方法。下面我们根据一个例子讲下ActiveX对象的使用方法。我们将使用三种方法完成。

例:画直线,根据图元名称获得其对象,并得到直线的两个端点。并将直线向x轴负方向挪动1000。

1.1 ActiveX对象属性的操作

(1) 选择直线工具,在cad绘图窗口中绘制一条直线

(2)打开Visual Lisp,在控制台窗口键入如下代码:


    
    
  1. _$ (vl-<span class="hljs-keyword"><span class="hljs-keyword">load</span></span>-com)</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">_$ (setq line- object (vlax-ename->vla- object (entlast)))
  2. #<VLA- OBJECT IAcadLine 0000000030624d58>

若要用ActiveX访问指定的图形对象,则可以先找到对象的图元名,再将这个名称转化为VLA对象,之后就可以按照访问VLA对象的方法访问了。通过上面两行代码,我们就得到了刚刚画的直线的对象,并保存在变量line-object中。

    右键变量line-object,选择【检验】。弹出【检验】窗口,这里我们可以看到这个变量的多个属性。其中<StartPoint>和<EndPoint>便是线段的起点和终点。这里我们看到<EndPoint>值为#<variant 8197…>,这是一种ActiveX型的数据类型,术语“变体”。变体是应用在ActiveX对象操作中使用的数据类型,可以通过内置的函数与AutoCAD中的数据相互转化,下面我们将看到应用。双击<EndPoint>,弹出子窗口,我们可以看到该变体的值是一个元素类型为Double的#<safearray…>,Safearray(安全数组)也是一种ActiveX数据类型。双击safearray,弹出子窗口我们终于看到终点坐标(1007.6 3440.77 0.0)。


图表 2 ActiveX对象检验

接下来我们使用Lisp代码完成读取工作


    
    
  1. _$ (setq endp (vla-get-endpoint line-object))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment"><span class="hljs-comment">#&lt;variant 8197 ...&gt;</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (setq endp2 (vlax-variant-value endp))
  2. #<safearray...>
  3. _$ (setq endp3 (vlax-safearray->list endp2))
  4. ( 1007.6 3440.77 0. 0)

其中vla-get-endpoint,vlax-variant-value,vlax-safearray->list是AutoLisp函数。同样如法炮制得到起点的坐标值:


    
    
  1. _$( setq startp3 (vlax-safearray->list (vlax-variant-value (vla-get-startpoint (vlax-ename->vla-object (entlast))))))
  2. ( 234.156 3400.91 0.0 )

接下来设置新的坐标


    
    
  1. _$ (setq newEndP (<span class="hljs-keyword"><span class="hljs-keyword">list</span></span> (- (nth <span class="hljs-number"><span class="hljs-number">0</span></span> endp3) <span class="hljs-number"><span class="hljs-number">1000</span></span>) (nth <span class="hljs-number"><span class="hljs-number">1</span></span> endp3) (nth <span class="hljs-number"><span class="hljs-number">2</span></span> endp3)))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">(<span class="hljs-number"><span class="hljs-number">7.6</span></span> <span class="hljs-number"><span class="hljs-number">3440.77</span></span> <span class="hljs-number"><span class="hljs-number">0.0</span></span>)</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">_$ (setq newStartP ( list (- (nth 0 startp3) 1000) (nth 1 startp3) (nth 2 startp3)))
  2. ( -765.844 3400.91 0.0)

接下来将新的坐标写入该对象,写入函数vla-put- 要求写入参数应当为变体类型,所以我们创建了两个安全数组,NewEndP2&NewStartP2。


    
    
  1. _$ (setq NewEndP2 (vlax-make-safearray vlax-vbDouble <span class="hljs-string"><span class="hljs-string"><span class="hljs-string">'(0 . 2)))</span></span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-string">#&lt;safearray...&gt;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-string">_$ (vlax-safearray-fill NewEndP2 NewEndP)
  2. #<safearray...>
  3. _$ (setq NewStartP2 (vlax-make-safearray vlax-vbDouble '</span>(<span class="hljs-number"><span class="hljs-number">0</span></span> . <span class="hljs-number"><span class="hljs-number">2</span></span>)))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment"><span class="hljs-comment">#&lt;safearray...&gt;</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (vlax-safearray-fill NewStartP2 NewStartP)
  4. #<safearray...>
  5. _$ (vla-put-startpoint line-object NewStartP2)</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-literal"><span class="hljs-literal">nil</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (vla-put-endpoint line-object NewEndP2)
  6. Nil

同样地,我们可以不用ActiveX,而是采用AutoCAD 内部命令来完成上述工作。


    
    
  1. _$(setq ent1 (entget (entlast)))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$(setq oldEndp (assoc 11 ent1)) ;终点坐标DXF组码值为 11
  2. _$ (setq oldStartp (assoc <span class="hljs-number"><span class="hljs-number">10</span></span> ent1)) ;起点坐标DXF组码值为<span class="hljs-number"><span class="hljs-number">10</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (setq newEndp (list 10 (- (nth 1 oldEndp) 1000) (nth 2 oldEndp) (nth 3 oldEndp)))
  3. _$ (setq newStartp (list <span class="hljs-number"><span class="hljs-number">10</span></span> (- (nth <span class="hljs-number"><span class="hljs-number">1</span></span> oldStartp) <span class="hljs-number"><span class="hljs-number">1000</span></span>) (nth <span class="hljs-number"><span class="hljs-number">2</span></span> oldStartp) (nth <span class="hljs-number"><span class="hljs-number">3</span></span> oldStartp)))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (setq ENT1 (subst newEndp oldEndp ENT1))
  4. _$ (setq ENT1 (subst newStartp oldStartp ENT1))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (entmod ENT1)

可能这时你就有疑问了,既然两种办法都可改变图元的属性,那还用ActiveX干嘛。其实相比于其他AutoCAD API环境,ActiveX接口技术速度快,效率高,随CAD安装,便于使用。另外ActiveX的对象交互技术使得CAD可与外界应用程序交互,拓宽了CAD开发的应用范围。

1.2 ActiveX对象属性的操作

Visual Lisp提供了Vlax-invoke-method函数来调用ActiveX的方法。使用的时候要注意将参数转化为ActiveX型,除非参数的默认分配类型(见将数据类型转换为ActiveX型)正好为所需的类型。对于上面的line-object,我们如何知道该对象所支持的ActiveX方法呢,下面提供个人经验。首先使用vlax-dump-object函数列出line-object所支持的方法。


    
    
  1. _$ (vlax-dump- object line- object t)
  2. ; IAcadLine: AutoCAD Line 接口
  3. ;特性值:
  4. ; Angle (RO) = 0.620333
  5. ; Application (RO) = #<VLA-OBJECT IAcadApplication 000000013f993318>
  6. ; Delta (RO) = ( 1361.03 972.338 0.0)
  7. ; Document (RO) = #<VLA-OBJECT IAcadDocument 000000002fb96bc8>
  8. ; EndPoint = ( 1458.44 1051.22 0.0)
  9. ; EntityTransparency = "ByLayer"
  10. ; Handle (RO) = "236"
  11. ; HasExtensionDictionary (RO) = 0
  12. ; Hyperlinks (RO) = #<VLA-OBJECT IAcadHyperlinks 0000000039a12ad8>
  13. ; Layer = "0"
  14. ; Length (RO) = 1672.68
  15. ; Linetype = "ByLayer"
  16. ; LinetypeScale = 1.0
  17. ; Lineweight = -1
  18. ; Material = "ByLayer"
  19. ; Normal = ( 0.0 0.0 1.0)
  20. ; ObjectID (RO) = 42
  21. ; ObjectID32 (RO) = 42
  22. ; ObjectName (RO) = "AcDbLine"
  23. ; OwnerID (RO) = 43
  24. ; OwnerID32 (RO) = 43
  25. ; PlotStyleName = "ByLayer"
  26. ; StartPoint = ( 97.4054 78.8798 0.0)
  27. ; Thickness = 0.0
  28. ; TrueColor = #<VLA-OBJECT IAcadAcCmColor 0000000039a12890>
  29. ; Visible = -1
  30. ;支持的方法:
  31. ; ArrayPolar ( 3)
  32. ; ArrayRectangular ( 6)
  33. ; Copy ()
  34. ; Delete ()
  35. ; GetBoundingBox ( 2)
  36. ; GetExtensionDictionary ()
  37. ; GetXData ( 3)
  38. ; Highlight ( 1)
  39. ; IntersectWith ( 2)
  40. ; Mirror ( 2)
  41. ; Mirror3D ( 3)
  42. ; <span style= "color:#ff0000;">Move ( 2)</span>
  43. ; Offset ( 1)
  44. ; Rotate ( 2)
  45. ; Rotate3D ( 3)
  46. ; ScaleEntity ( 2)
  47. ; SetXData ( 2)
  48. ; TransformBy ( 1)
  49. ; Update ()

这里我们看到有个名字为Move的方法,猜想其可以完成图元的移动,是否如此呢,查看帮助中的“AutoCAD ActiveX and VBA references”部分,查找Move Method,确实是我们预想的那样。接下来我们使用这个函数同样完成将直线向x轴负方向挪动1000的工作。Move方法接受两个参数,Point1&Point2,分别表示移动向量的起点和终点。显然这里Point1&Point2的坐标分别为(0 , 0 , 0)和 (-1000 , 0 , 0)。参数类型要求为Variant (three-element array of doubles),我们先构造两个double类型的safearray,然后转化为变体(Variant )类型。(转化为变体类型这一步并非必须,因为safearray会被强制转化为Variant)最后作为实参代入函数,看能否同样完成前面的工作。


图表 3 Move方法帮助

 


    
    
  1. _$ (setq Point1 (vlax-make-safearray vlax-vbDouble <span class="hljs-string"><span class="hljs-string"><span class="hljs-string">'(0 . 2)))</span></span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-string">#&lt;safearray...&gt;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-string">_$ (setq Point2 (vlax-make-safearray vlax-vbDouble '( 0 . 2)))
  2. #<safearray...>
  3. _$ (vlax-safearray-fill Point1 (list <span class="hljs-number"><span class="hljs-number">0</span></span> <span class="hljs-number"><span class="hljs-number">0</span></span> <span class="hljs-number"><span class="hljs-number">0</span></span>))</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment"><span class="hljs-comment">#&lt;safearray...&gt;</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (vlax-safearray-fill Point2 (list - 1000 0 0))
  4. #<safearray...>
  5. _$ (setq Point1 (vlax-make-variant Point1)) ;;转换为变体类型,非必须</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-comment"><span class="hljs-comment">#&lt;variant 8197 ...&gt;</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-number"><span class="hljs-number">_</span></span>$ (setq Point2 (vlax-make-variant Point2)) ;;非必须
  6. #<variant 8197 ...>
  7. _$ (vlax-invoke-method line-object "Move" Point1 Point2)
  8. Nil

然后将窗口切换到AutoCAD绘图窗口,直线确实按照我们预想的一样,又往x轴负方向移动了1000单位。

总结:对于某一ActiveX对象,使用vlax-dump-object函数可以列出该对象的属性值和适用的ActiveX方法。对属性值的操作,可以采用vla-get和vla-put为前缀的函数。ActiveX方法就比较复杂,若要查找相应的操作函数的使用方法,可以参考AutoCAD帮助中的“AutoCAD ActiveX and VBA references”部分。并应用vlax-invoke-method方法调用ActiveX对象的方法。CAD2013版本以后,VBA开发不再随软件安装,所以帮助部分也不容易找到了。http://entercad.ru/acadauto.en/ 网站可供参考使用。

 2.ActiveX对象交互

在Visual Lisp环境中,也可以使用其他应用程序的ActiveX对象。笔者在开发的时候,遇到XML和CAD信息交互的问题,上网搜索,发现没有解析XML的LISP库,如果自己写XML解析,势必大大影响项目进展。终于在ActiveX对象中找到灵感,下载了一个XML的ActiveX控件,加载到自己的程序里完成项目开发。(见我的另一篇博客,AutoLisp中XML解析方案


【欢迎转载,请注明出处】


        </div>
            </div>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值