青华模具培训学校

 找回密码
 注册

QQ登录

只需一步,快速开始

青华模具培训学院
查看: 1450|回复: 0

NET平台的AutoCAD二次开发介绍

[复制链接]
发表于 2011-2-22 14:17 | 显示全部楼层 |阅读模式
本文基于AutoCAD 2006新推出的.NET API为工具,介绍了在.NET平台下对AutoCAD进行二次开发的技术,并与目前常用的VBA、ObjectARX作了对比。同时讨论了如何弥补.NET API某些不足的功能。& n' ~4 F+ z7 P  |! w2 N$ S
+ E# P/ f4 q6 L" x5 D& P7 D

  G* r8 v! p9 m. L( E% L' `' ~当前AutoCAD的二次开发工具主要有:VisualLisp、VBA和ObjectARX等。其中,VisualLisp与VBA较为简单,特别是VBA,使用方便且开发速度较快,但其功能相比ObjectARX有所不足,尤其是对面向对象的功能支持不好。而ObjectARX基于VC平台,在C 的支持下,其功能非常强大,可以很好地运用各种面向对象技术,但其缺点是发开速度比较慢,同时对开发人员的能力要求较高。' Y0 h8 z6 {7 F4 g, |% Z

- K3 ]. s9 P; i' J.NET是微软新推出的开发平台,具有众多优点。基于.NET平台对AutoCAD进行二次开发,可充分利用.NET的各种优势,在保证功能强大的前提下大大提高开发速度。
4 V% c5 x8 w7 |  }- C
# M( ^3 l0 ]& R" b4 n/ S& ]一、基于.NET的开发: j+ Q- b- I  @
1 G# C+ j& p* q6 g8 C+ O- B, R9 @0 h
1..NET API简介# ~7 e5 w$ |4 o0 C# r. j

1 g( @( ~' t" d" L) X/ t+ H在新推出的AutoCAD 2006中,Autodesk为其开发增加了.NET API。.NET API提供了一系列托管的外包类(Managed Wrapper Class),使开发人员可在.NET框架下,使用任何支持.NET的语言,如VB.NET、C# 和Managed C 等对AutoCAD进行二次开发。其优点是完全面向对象,在拥有与C 相匹配的强大功能的同时,具有方便易用的特点,是较理想的AutoCAD二次开发工具。
; R, v' a5 ^/ T+ r6 j0 ?  Q
' H5 }" N! R- M$ r5 ^+ _; l& W2..NET API与传统ObjectARX的主要区别
5 ?. b* F" f. Y
5 b2 n& X, P# N# d* o1 F% Y# E.NET API与传统ObjectARX的区别主要源于在.NET环境下开发应用程序与在VC环境下开发应用程序的区别。首先,在VC环境下,程序员需要自己管理内存的申请和释放,而.NET采用了垃圾回收机制,由.NET框架自行判断内存回收的时机并实行回收,从而解决了令C 程序员头痛的内存泄漏问题。也正是由于这个特点,在.NET环境下不能象在C 环境下那样利用析构函数释放其他的资源,需要程序员在程序中显式地释放。在.NET API中,主要通过Dispose来函数进行资源的释放。) J6 u/ a' U+ y' U0 o& y. [

* V2 X' m! K+ W- m% W+ L其次,ObjectARX中的各种反应器(Reactor)在.NET API中由外包类映射为各种事件(Event),可通过定义这些事件的响应函数来响应AutoCAD的各种操作。同时对于错误信息的处理也从函数返回值改变为通常异常来处理,使其更好地兼容.NET。由于VB.NET、C#等语言都是完全面向对象的,没有全局函数的概念,所以.NET API将ObjectARX下的全局函数封装为.NET API下的某些对象或对象的属性,如ObjectARX下与用户交互的系列全局函数被封装为CommandLinePrompt类。% g( D6 ]- c2 |

7 s) y0 I' C& X0 Y( f8 ~3.使用.NET API4 p7 j& }1 b$ G) }4 R
4 W" `. a% o. {! T5 ~* i7 ~  a
下面以C#为例,在Microsoft Visual C# 2005 Express Edition Beta平台上,先新建一个Class Library项目,再将AutoCAD2005安装目录下的acdbmgb.dll与acmgb.dll作为引用添加进项目中。这两个文件包含了.NET API中所有的外包类。# d& n' e: H! K. o/ @2 {! |' B

' z6 t; y8 h0 y1 _- j& r8 B" N% x, M9 D4 g
然后在要使用.NET API的类中添加以下语句以引用.NET API的命名空间。需要添加的语句如下:7 j  Z8 M% s; d. i0 Q# G

$ E8 d: c: ~" d( Zusing Autodesk.AutoCAD.ApplicationServices;9 U/ G" L; `- m% I8 m
using Autodesk.AutoCAD.DatabaseServices;
) O5 a9 [9 P- E, x; @using Autodesk.AutoCAD.Runtime;4 K  W; l$ \* x0 G; K. V
using Autodesk.AutoCAD.Geometry;
1 ^9 m8 m# P9 `# q1 f
$ {+ W% k3 v6 {- y% c
这样就可以利用.NET API进行开发了。以下代码可在AutoCAD注册为一个命令“AddLine”,该命令可在当前工作空间中添加一条起点为(0,0,0),终点(200,200,0)的直线。代码如下:
! I, n* |' R! q
% ^9 x4 z- T! O2 |! x[CommandMethod ("AddLine")]
- D7 O) o6 _, z7 m3 Spublic static void AddLineCmd()
) o! n) y- q3 e9 N# F+ B, |9 G{9 l) T! s. D9 o  Q- p3 V6 |
Database db = HostApplicationServices.WorkingDatabase;//获得当前工作空间的数据库
) U$ o$ n+ t7 h: e$ ^& X4 lBlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead); //获得块表
# j- O: C( u( W- O) ^1 L2 dBlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite); //获得模型空间的块表记录/ L6 O: z7 }2 C2 t4 y
Line line = new Line(new Point3d(0, 0, 0), new Point3d(200, 200, 0));//创建一条直线" ^; p. K. |: ?, W+ R) q' Q" d9 N
try {
" C7 Y. ?! H4 G3 pbtr.AppendEntity(line);//将直线添加到模型空间中0 W) X, M  n; p' g5 ]; ^  S8 l
line.Close();//关闭该直线/ e8 y6 a; N% }8 P: u3 }
}
1 i5 s0 v: a8 |& x- K/ m& W9 [7 `finally {
3 A; e6 W! ^! s+ Rbtr.Close();//关闭块表记录
0 u9 d0 R# k" H+ r" ]bt.Close();//关闭块表
' N# R, N" T) d& t}3 A5 K5 S  W% [  E8 n+ _; S
}
" V6 J3 ?( D. f

$ C; E7 {6 l4 j3 `由此可见,上述语句与在VC下的开发非常类似,其过程都是先得到数据库,然后依次打开块表、块表记录,接着添加实体,最后关闭块表、块表记录。值得注意的是finally语句,无论try块中的语句是否发生异常,finally块中的语句都会被执行,从而确保关闭块表和块表记录的操作会被执行。
) c  m0 O- Q: R' i2 Y  y
  ^4 \' O8 y+ d' q. C写完代码后进行编译,编译完成将得到一个dll文件。在AutoCAD 2006中通过“netload”命令即可选择该dll文件进行加载,加载成功后即可以通过“AddLine”命令执行上述代码。遗憾的是目前的.NET API版本还不支持卸载,若要卸载只能关闭AutoCAD。9 z" n$ K8 F! j8 K
# C7 m8 V3 y: o' y  H* h
4..NET API的初始化与清除4 w: h: Z$ W& }& i
7 U2 t4 M$ D# J: `6 L0 K
在ObjectARX中,“acrxEntryPoint”函数是ARX程序的载入点,程序的初始化和清除均可在该函数中进行。而在.NET API中则首先需要将初始化代码封装在一个类中,同时该类需要压迫实现% [9 n8 Q# b% U! @
IExtensionApplication接口。该接口包含Initialize与Terminate两个函数。其中Initialize负责加载程序时的初始化操作,Terminate则负责进行卸载程序时的清除操作。代码如下:

) T+ q; f) G( z8 `2 Z
$ o" n7 z$ b1 m8 k1 \  Gnamespace ARXExample {
+ J: ?3 F+ o! j7 w3 Y" I& Npublic class MyARX : IExtensionApplication {
- C! _$ n4 z9 p……
2 g- Q6 o( t5 m* q& k; ?public void Initialize() {0 T) E5 d2 c# f4 s2 D! d
//初始化操作
2 F% Q; B5 h' u}
8 p' O, i6 S% u0 M* m/ n3 xpublic void Terminate() {9 d4 [4 @/ x7 N1 t) J
- |  G: t/ r4 I
//清除操作
  N) H5 `, H" |' M, G}+ a, a( W; y8 b
……
/ S* @) [/ B) n# E# d" A' M. Q' h7 ~9 N
}4 [' S$ y6 m9 B; T' _
同时,为加快加载速度,可在MyARX.cs的文件头加入以下语句:
. y7 U+ |: f3 ]0 c7 d[assembly: ExtensionApplication (typeof (ARXExample.MyARX) ) ]
% Y$ m' o; T# ?! q0 T[assembly: CommandClass (typeof (ARXExample.MyARX) ) ]
  Q! `' [1 b/ s

) ~  M5 j3 d+ U/ V  S% E( c! F这样在加载程序时AutoCAD将直接通过MyARX中的Initialize语句进行初始化,同时注册MyARX中的命令。否则,AutoCAD将搜索dll中所有的类以找到实现IExtensionApplication接口的类进行初始化,如找不到则不进行初始化。同样,通过CommandClass属性,AutoCAD也会直接到MyARX类中搜索要注册的命令。当程序中包含的类数目较多时,通过ExtensionApplication和CommandClass这两个属性可显著地加快程序的加载速度。! ?9 `2 z9 ^+ B! e' @  R- t$ _1 S" @
- n/ F/ S+ W  J& y% I1 J
5..NET API与COM交互操作6 I1 }3 `) p% L4 Z4 V

* E1 S. l4 |& M6 E在目前的.NET API中,其功能与传统的ObjectARX相比有所不及,有相当的ObjectARX函数目前还没有封装到.NET API中,如GetPoint等。但可以通过COM方式使用ActiveX来弥补.NET API的不足。2 r2 ], F( `' I" s7 p
增加了COM引用后,程序就可以使用许多VBA中的功能了。以AutoCAD ActiveX中的事件为例,以下代码可以为当前工作空间中所有的图元添加Modified事件:
8 i, k2 r# r9 W, d  Q& r

- h& y% @% n, [( F; S' M0 sDatabase db = HostApplicationServices.WorkingDatabase;
& T1 I3 Y  f) q! q  M8 O* `, lBlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead);
, h$ g& H8 G* ]$ |( ^" U& DBlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite);
( L* i5 @8 P3 R0 Vtry {
, u# D. V' q+ k4 C: j( X' tAcadObject obj;
8 g7 A2 w% N: ], x: g//遍历块表记录! B% {- _# [% X6 P& d1 c
foreach (ObjectId objId in btr) {
1 j5 h7 V: N* f6 R+ x5 }' o" I: T//由ObjectId得到ActiveX中的AcadObject对象
  }( A. _. c) ]2 D+ eobj = (AcadObject)((AcadDatabase)db.AcadDatabase).ObjectIdToObject(objId.OldId);( ]( U9 y) t' ~
//为obj添加响应Modified事件
, {" q# s& y, W3 y$ X( Xobj.Modified = new IAcadObjectEvents_ModifiedEventHandler(obj_Modified);4 X4 O2 L, v8 J5 Q! t! h% L- W1 D: f
}
0 ^# l$ R: `& g8 H/ p}* J  E' i0 m: O, p  c# H  I' j
finally {
" u# c8 H+ E5 c+ ^6 v  D$ m+ ebtr.Close();- p5 `3 ^5 X( P- N- H* J
bt.Close();4 b- r( l% b3 P4 s2 w, P
}; A: I+ S  K2 ?" C
其中事件响应函数obj_Modified的表示如下所示:
! s% i: k# K( @+ A( N6 G, ppublic static void obj_Modified(AcadObject obj) {5 h4 y4 t. f* P1 |( B1 Y
CommandLinePrompts.Message("object modified!" obj.ObjectID "\n");+ k7 Z$ y4 ]1 ?5 B( i; P1 X
}

& j# y2 p; K5 N2 V1 E
4 s2 a* ~& I5 o4 n- ~二、结论  y, U; b0 h7 G, E

2 H1 k; a/ o% r% l- Q+ ~本文以C#为例,对基于.NET API的AutoCAD二次开发作了较详细的介绍。.NET API在具有ObjectARX强大功能的同时具有VBA使用方便易用的优点,同时具有C 的强大功能,是较为理想的开发工具。但目前.NET API在某些方面还有些不足,但随着其版本的更新、完善,定会成为众多开发人员的首选工具。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|关于我们|sitemap|小黑屋|Archiver|手机版|UG网-UG技术论坛-青华数控模具培训学校 ( 粤ICP备15108561号 )

GMT+8, 2025-2-11 21:48 , Processed in 0.055497 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表