青华模具培训学校

 找回密码
 注册

QQ登录

只需一步,快速开始

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

NET平台的AutoCAD二次开发介绍

[复制链接]
发表于 2011-2-22 14:17 | 显示全部楼层 |阅读模式
本文基于AutoCAD 2006新推出的.NET API为工具,介绍了在.NET平台下对AutoCAD进行二次开发的技术,并与目前常用的VBA、ObjectARX作了对比。同时讨论了如何弥补.NET API某些不足的功能。
. d1 Z& j$ {6 s( U9 s, u- @: a" J" h, M3 |8 A9 i5 i

+ a! t7 n0 y( L# c当前AutoCAD的二次开发工具主要有:VisualLisp、VBA和ObjectARX等。其中,VisualLisp与VBA较为简单,特别是VBA,使用方便且开发速度较快,但其功能相比ObjectARX有所不足,尤其是对面向对象的功能支持不好。而ObjectARX基于VC平台,在C 的支持下,其功能非常强大,可以很好地运用各种面向对象技术,但其缺点是发开速度比较慢,同时对开发人员的能力要求较高。
0 M2 L9 x. H8 o4 y( O
) U! @7 e% r3 b4 {% i.NET是微软新推出的开发平台,具有众多优点。基于.NET平台对AutoCAD进行二次开发,可充分利用.NET的各种优势,在保证功能强大的前提下大大提高开发速度。: t( w* h2 v. o" I% N: M

6 R+ G3 t* ?; Y一、基于.NET的开发
& ^, D1 _$ p$ U4 k; i: S
6 m! _4 A' ?9 F8 e. @  N! a9 }1..NET API简介) n/ m5 s4 D8 F5 u% k
9 J  n% q$ [( S- ~2 n
在新推出的AutoCAD 2006中,Autodesk为其开发增加了.NET API。.NET API提供了一系列托管的外包类(Managed Wrapper Class),使开发人员可在.NET框架下,使用任何支持.NET的语言,如VB.NET、C# 和Managed C 等对AutoCAD进行二次开发。其优点是完全面向对象,在拥有与C 相匹配的强大功能的同时,具有方便易用的特点,是较理想的AutoCAD二次开发工具。# @0 e% ?- n+ @
5 e6 m1 g- b9 E3 n- m
2..NET API与传统ObjectARX的主要区别
: T$ X6 v/ X$ D3 B' E" E0 r
. ^) T! K) F; r; K.NET API与传统ObjectARX的区别主要源于在.NET环境下开发应用程序与在VC环境下开发应用程序的区别。首先,在VC环境下,程序员需要自己管理内存的申请和释放,而.NET采用了垃圾回收机制,由.NET框架自行判断内存回收的时机并实行回收,从而解决了令C 程序员头痛的内存泄漏问题。也正是由于这个特点,在.NET环境下不能象在C 环境下那样利用析构函数释放其他的资源,需要程序员在程序中显式地释放。在.NET API中,主要通过Dispose来函数进行资源的释放。
& R/ Z! q# U+ l  T1 ^& s. X" O3 m6 v( J2 ~6 y0 g- l
其次,ObjectARX中的各种反应器(Reactor)在.NET API中由外包类映射为各种事件(Event),可通过定义这些事件的响应函数来响应AutoCAD的各种操作。同时对于错误信息的处理也从函数返回值改变为通常异常来处理,使其更好地兼容.NET。由于VB.NET、C#等语言都是完全面向对象的,没有全局函数的概念,所以.NET API将ObjectARX下的全局函数封装为.NET API下的某些对象或对象的属性,如ObjectARX下与用户交互的系列全局函数被封装为CommandLinePrompt类。% I$ D' ?. \; x4 s
+ I% Y6 j- n; \! O3 W: c6 l
3.使用.NET API; ^9 |3 ^6 c# `5 B  U
( A* p! `3 ]8 h) V8 P7 o: |2 h
下面以C#为例,在Microsoft Visual C# 2005 Express Edition Beta平台上,先新建一个Class Library项目,再将AutoCAD2005安装目录下的acdbmgb.dll与acmgb.dll作为引用添加进项目中。这两个文件包含了.NET API中所有的外包类。
, ]) K: q1 K. I; x
4 s6 x0 `1 Y! v) Y5 ~' E: [! \1 ^7 c4 B3 _
然后在要使用.NET API的类中添加以下语句以引用.NET API的命名空间。需要添加的语句如下:
, H+ b5 V+ h) x& s# w. j
8 z( P) R- Z( @) n6 \using Autodesk.AutoCAD.ApplicationServices;# ]- M4 _. q" [
using Autodesk.AutoCAD.DatabaseServices;
' y- S0 n7 K7 d+ P' cusing Autodesk.AutoCAD.Runtime;
9 I! @$ r( v3 u, K, s0 gusing Autodesk.AutoCAD.Geometry;
% W& P* a1 X; j! n8 v+ w4 x1 J7 h

8 {/ z* X& k4 x/ m3 a这样就可以利用.NET API进行开发了。以下代码可在AutoCAD注册为一个命令“AddLine”,该命令可在当前工作空间中添加一条起点为(0,0,0),终点(200,200,0)的直线。代码如下:
- n% i6 K; z& e
1 }! |! l/ B1 p! g% x8 `0 H8 F[CommandMethod ("AddLine")]( s6 n0 t) \) y. C2 P, C
public static void AddLineCmd()
! ~- m7 f- `% e{
! E7 }/ r- b0 l* G! h5 NDatabase db = HostApplicationServices.WorkingDatabase;//获得当前工作空间的数据库
. `. E, M" f$ w; X/ {/ uBlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead); //获得块表
5 ~* Q& O: Y0 V/ iBlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite); //获得模型空间的块表记录
( l# C1 T0 W2 g3 [7 HLine line = new Line(new Point3d(0, 0, 0), new Point3d(200, 200, 0));//创建一条直线" l0 u. v, h* t2 a  C
try {
, ]2 N1 s9 u! H1 I, pbtr.AppendEntity(line);//将直线添加到模型空间中
, P4 S, c4 w1 M8 a$ `6 t2 p& f" Vline.Close();//关闭该直线7 d' H5 K) P! z) Y: M2 i
}
. s0 s# o# Q  Q- E9 j4 c( Qfinally {  L% _7 d, X1 Q' u
btr.Close();//关闭块表记录% r3 a6 M3 ^7 o9 |
bt.Close();//关闭块表
0 v, d9 e3 f( i0 x}
  h9 W+ b) i" ?$ w/ q8 t}
- E/ A* o" t! H8 ]

7 q" X. ]7 E) E0 I# w由此可见,上述语句与在VC下的开发非常类似,其过程都是先得到数据库,然后依次打开块表、块表记录,接着添加实体,最后关闭块表、块表记录。值得注意的是finally语句,无论try块中的语句是否发生异常,finally块中的语句都会被执行,从而确保关闭块表和块表记录的操作会被执行。3 Z/ `& C0 g: ?4 `5 F  A) T
$ S# d% F: I, m
写完代码后进行编译,编译完成将得到一个dll文件。在AutoCAD 2006中通过“netload”命令即可选择该dll文件进行加载,加载成功后即可以通过“AddLine”命令执行上述代码。遗憾的是目前的.NET API版本还不支持卸载,若要卸载只能关闭AutoCAD。8 W& }9 e* L2 ]5 Z

! e( v+ B" ?' P: G4..NET API的初始化与清除
9 v# K; f7 m7 V+ P6 [5 Y) |9 a# k
! Y5 R% C2 K) h在ObjectARX中,“acrxEntryPoint”函数是ARX程序的载入点,程序的初始化和清除均可在该函数中进行。而在.NET API中则首先需要将初始化代码封装在一个类中,同时该类需要压迫实现4 N$ V& @3 A* n4 }3 x
IExtensionApplication接口。该接口包含Initialize与Terminate两个函数。其中Initialize负责加载程序时的初始化操作,Terminate则负责进行卸载程序时的清除操作。代码如下:
+ r& g9 ^- X# a  I: i- ~, u

$ |5 c8 w* ?3 K: U( Knamespace ARXExample {9 l5 K* `9 K# F" u) l7 f1 G
public class MyARX : IExtensionApplication {4 s. w* r$ j9 j, O
……6 D/ g  I" F6 _9 G( e# z
public void Initialize() {* ^& v! ], ?* ]8 T2 B
//初始化操作) B# Y7 b, A& F+ f
}! w$ j7 @  x$ K7 U* y" P' x" [
public void Terminate() {
% x" B; C+ e/ t  X
4 y5 O0 V/ b1 ]3 g. C//清除操作
8 w! N  l6 L0 Z/ n! U/ @  m# d3 m}
. e- n: }1 _; y9 S9 X- |……
/ O5 s- H1 H3 m, R% p# J
' r8 W% V5 o7 u) o+ Q: ^# S  c+ W4 E}
' T2 ^  c8 M" E3 j0 e; T) i同时,为加快加载速度,可在MyARX.cs的文件头加入以下语句:  J4 s: _4 \1 @' D
[assembly: ExtensionApplication (typeof (ARXExample.MyARX) ) ]
. ]& M& Q' \) \; }/ p[assembly: CommandClass (typeof (ARXExample.MyARX) ) ]

" w  Y, D1 N  M2 q) K# c: I  a8 v6 c6 u4 L9 J' x& e7 O3 b
这样在加载程序时AutoCAD将直接通过MyARX中的Initialize语句进行初始化,同时注册MyARX中的命令。否则,AutoCAD将搜索dll中所有的类以找到实现IExtensionApplication接口的类进行初始化,如找不到则不进行初始化。同样,通过CommandClass属性,AutoCAD也会直接到MyARX类中搜索要注册的命令。当程序中包含的类数目较多时,通过ExtensionApplication和CommandClass这两个属性可显著地加快程序的加载速度。- a* s2 ~( B2 q; L/ b

" W7 F6 v! v9 h! f1 R  i6 S, r5..NET API与COM交互操作
* ^$ m8 {% z  \
& d. Q+ |# G! [# W  R2 z在目前的.NET API中,其功能与传统的ObjectARX相比有所不及,有相当的ObjectARX函数目前还没有封装到.NET API中,如GetPoint等。但可以通过COM方式使用ActiveX来弥补.NET API的不足。; x  m0 u5 I" j8 ]' t7 X: ~
增加了COM引用后,程序就可以使用许多VBA中的功能了。以AutoCAD ActiveX中的事件为例,以下代码可以为当前工作空间中所有的图元添加Modified事件:
: U" I# w$ e# @# [+ S

6 l: i/ J; k. E/ MDatabase db = HostApplicationServices.WorkingDatabase;
7 `7 K6 Z5 w. `; R+ VBlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead);
" v1 T  l! g1 R  K% kBlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite);
& b$ b8 m: P/ Z  ?7 m: y7 Y3 ttry {
. K4 c" `1 r* ~% ]( |2 @7 QAcadObject obj;/ D# q$ x1 Z5 T% r% H$ @
//遍历块表记录
7 I5 d! ?" J& K, a) r9 Aforeach (ObjectId objId in btr) {
7 l+ d' |/ }9 K5 N//由ObjectId得到ActiveX中的AcadObject对象
2 `) s- L3 [& ~# ]obj = (AcadObject)((AcadDatabase)db.AcadDatabase).ObjectIdToObject(objId.OldId);
% @. h) D5 a1 q1 a6 N9 Q6 V6 A//为obj添加响应Modified事件
# F- J7 ~3 [. x- m; t9 l7 vobj.Modified = new IAcadObjectEvents_ModifiedEventHandler(obj_Modified);
  p( u9 v* U* O}6 }' K' i9 V; c0 @
}/ w  h8 }3 h7 |  M( Q& u
finally {
7 b7 U# d- T0 V! H4 I7 lbtr.Close();' j8 U9 G0 ^5 X4 a8 q
bt.Close();
" @; G$ C) ~3 k- c! R9 m}
; Q$ G+ Z7 t) {1 l$ s+ d2 v其中事件响应函数obj_Modified的表示如下所示:8 R6 @# M9 X; X2 U- \
public static void obj_Modified(AcadObject obj) {9 T/ M& ^. P  a9 d7 n
CommandLinePrompts.Message("object modified!" obj.ObjectID "\n");
5 r/ m' D: x; ?$ m}
+ i5 ~8 s& S- G- r) y
: u: Q) E/ Y; ?' F" v
二、结论
4 a: o7 c3 s6 [+ M' f; t0 E3 v; Y: I6 Q1 o9 c
本文以C#为例,对基于.NET API的AutoCAD二次开发作了较详细的介绍。.NET API在具有ObjectARX强大功能的同时具有VBA使用方便易用的优点,同时具有C 的强大功能,是较为理想的开发工具。但目前.NET API在某些方面还有些不足,但随着其版本的更新、完善,定会成为众多开发人员的首选工具。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-17 10:56 , Processed in 0.053280 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

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