青华模具培训学校

 找回密码
 注册

QQ登录

只需一步,快速开始

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

NET平台的AutoCAD二次开发

[复制链接]
发表于 2011-2-24 16:23 | 显示全部楼层 |阅读模式
当前AutoCAD的二次开发工具主要有:VisualLisp、VBA和ObjectARX等。其中,VisualLisp与VBA较为简单,特别是VBA,使用方便且开发速度较快,但其功能相比ObjectARX有所不足,尤其是对面向对象的功能支持不好。而ObjectARX基于VC平台,在C++的支持下,其功能非常强大,可以很好地运用各种面向对象技术,但其缺点是发开速度比较慢,同时对开发人员的能力要求较高。
& ~3 v6 {% a9 N    .NET是微软新推出的开发平台,具有众多优点。基于.NET平台对AutoCAD进行二次开发,可充分利用.NET的各种优势,在保证功能强大的前提下大大提高开发速度。
  @1 b0 r& u9 _5 w一、基于.NET的开发
5 }" b' N9 |( H! |    1..NET API简介
" T: ?+ ^2 E- U2 ?- S" t/ x  h    在新推出的AutoCAD 2006中,Autodesk为其开发增加了.NET API。.NET API提供了一系列托管的外包类(Managed Wrapper Class),使开发人员可在.NET框架下,使用任何支持.NET的语言,如VB.NET、C# 和Managed C++等对AutoCAD进行二次开发。其优点是完全面向对象,在拥有与C++相匹配的强大功能的同时,具有方便易用的特点,是较理想的AutoCAD二次开发工具。
2 U5 p3 ?! H, c4 }+ }. x9 K' n0 j* D    2..NET API与传统ObjectARX的主要区别" z+ w  O& [- G
    .NET API与传统ObjectARX的区别主要源于在.NET环境下开发应用程序与在VC环境下开发应用程序的区别。首先,在VC环境下,程序员需要自己管理内存的申请和释放,而.NET采用了垃圾回收机制,由.NET框架自行判断内存回收的时机并实行回收,从而解决了令C++程序员头痛的内存泄漏问题。也正是由于这个特点,在.NET环境下不能象在C++环境下那样利用析构函数释放其他的资源,需要程序员在程序中显式地释放。在.NET API中,主要通过Dispose来函数进行资源的释放。* D4 Q; T' V2 O- i0 K! }
    其次,ObjectARX中的各种反应器(Reactor)在.NET API中由外包类映射为各种事件(Event),可通过定义这些事件的响应函数来响应AutoCAD的各种操作。同时对于错误信息的处理也从函数返回值改变为通常异常来处理,使其更好地兼容.NET。由于VB.NET、C#等语言都是完全面向对象的,没有全局函数的概念,所以.NET API将ObjectARX下的全局函数封装为.NET API下的某些对象或对象的属性,如ObjectARX下与用户交互的系列全局函数被封装为CommandLinePrompt类。
+ Z1 K- S  n. c! q    3.使用.NET API6 p, c, c# x, r7 P, G& Q2 m( O! S
    下面以C#为例,在Microsoft Visual C# 2005 Express Edition Beta平台上,先新建一个Class Library项目,再将AutoCAD2005安装目录下的acdbmgb.dll与acmgb.dll作为引用添加进项目中。这两个文件包含了.NET API中所有的外包类。
# x2 z& ]9 d' ~: k& {6 W9 s0 O    然后在要使用.NET API的类中添加以下语句以引用.NET API的命名空间。需要添加的语句如下:
& e1 r: Z# |3 z  d2 z    using Autodesk.AutoCAD.ApplicationServices;; y& Q+ E& G% s( I+ k" S4 h0 v' ~/ ]  Z
    using Autodesk.AutoCAD.DatabaseServices;
6 q2 T& V6 ]- ~: v' v4 f    using Autodesk.AutoCAD.Runtime;
5 K8 X9 p: x- P* A" [0 E3 j    using Autodesk.AutoCAD.Geometry;
0 d! d( C1 U  O" s* L    这样就可以利用.NET API进行开发了。以下代码可在AutoCAD注册为一个命令“AddLine”,该命令可在当前工作空间中添加一条起点为(0,0,0),终点(200,200,0)的直线。代码如下:9 K# v4 O9 }+ |0 ^: R% h# {9 S5 a6 |
    [CommandMethod ("AddLine")]. v' d& M6 P) _
    public static void AddLineCmd()( X7 S4 q/ E$ p" G0 g. e
    {' P& t1 F8 n2 s! D5 O4 T9 k
    Database db = HostApplicationServices.WorkingDatabase;//获得当前工作空间的数据库
  b& C' w* W  ^+ K* {" o( o% x) U    BlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead); //获得块表/ E% z" B) V  a" a5 N+ P
    BlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite); //获得模型空间的块表记录
  G8 R+ Y6 q3 R. o% [2 D% F: |7 I    Line line = new Line(new Point3d(0, 0, 0), new Point3d(200, 200, 0));//创建一条直线! ^, i( C4 @' Q1 p, j! Y4 f7 V" r
    try {
; O2 s+ b4 h9 m3 j8 a% n    btr.AppendEntity(line);//将直线添加到模型空间中# B7 Q; o: G6 I* ]4 j
    line.Close();//关闭该直线1 ?- ^8 S8 l2 U" b- \
    }
0 K; h! k- a: i/ |2 I    finally {
0 n; {. j* V0 x% Z    btr.Close();//关闭块表记录- g# o1 b9 A0 c, F9 B1 W
    bt.Close();//关闭块表
, u) K1 u' P1 v    }
4 ]6 V- e# ?4 \6 d# i$ w1 p1 f    }
+ J& ?  P- |# t& r5 M    由此可见,上述语句与在VC下的开发非常类似,其过程都是先得到数据库,然后依次打开块表、块表记录,接着添加实体,最后关闭块表、块表记录。值得注意的是finally语句,无论try块中的语句是否发生异常,finally块中的语句都会被执行,从而确保关闭块表和块表记录的操作会被执行。- S$ m8 N: y: ^- u  r
    写完代码后进行编译,编译完成将得到一个dll文件。在AutoCAD 2006中通过“netload”命令即可选择该dll文件进行加载,加载成功后即可以通过“AddLine”命令执行上述代码。遗憾的是目前的.NET API版本还不支持卸载,若要卸载只能关闭AutoCAD。# v& Y& A5 D1 B1 }/ q# \1 p8 k
    4..NET API的初始化与清除
* P8 Y- V. T& B9 e" `0 j! L1 P    在ObjectARX中,“acrxEntryPoint”函数是ARX程序的载入点,程序的初始化和清除均可在该函数中进行。而在.NET API中则首先需要将初始化代码封装在一个类中,同时该类需要压迫实现
! j6 R9 o2 S' R) j. \' f# L! A    IExtensionApplication接口。该接口包含Initialize与Terminate两个函数。其中Initialize负责加载程序时的初始化操作,Terminate则负责进行卸载程序时的清除操作。代码如下:* f" y) c" y: t( V9 Y  V
namespace ARXExample {
6 B* J) L- I. j4 I- Ipublic class MyARX : IExtensionApplication {. F9 G( S7 d) z$ ]9 @- x: Q
……' n+ W3 J1 d' l; v9 w2 M. ^. l6 W& P" z
public void Initialize() {( f) v/ \* E7 b2 l* C+ b
//初始化操作9 I$ y' F+ C8 ?; n
}
7 V: j  q, [# r3 Z, spublic void Terminate() {
1 Y4 }" R9 h- s! l1 s# W6 @- K! j      //清除操作! c( U; H8 }3 c2 c
}
7 b6 G) x7 F+ P/ C……
7 l7 k+ U. ?4 j6 Q
, A5 P' |- ]: B( P# f5 E. a) o% m( U) c}8 s: P, b% b3 P8 w$ `
同时,为加快加载速度,可在MyARX.cs的文件头加入以下语句:) S! J# h' t8 x6 d
[assembly: ExtensionApplication (typeof (ARXExample.MyARX) ) ]0 O2 B7 d/ P- d. p) ^
[assembly: CommandClass (typeof (ARXExample.MyARX) ) ]
8 ~4 Y' K9 F4 d: O    这样在加载程序时AutoCAD将直接通过MyARX中的Initialize语句进行初始化,同时注册MyARX中的命令。否则,AutoCAD将搜索dll中所有的类以找到实现IExtensionApplication接口的类进行初始化,如找不到则不进行初始化。同样,通过CommandClass属性,AutoCAD也会直接到MyARX类中搜索要注册的命令。当程序中包含的类数目较多时,通过ExtensionApplication和CommandClass这两个属性可显著地加快程序的加载速度。5 q" j" x* X- e3 z, m
    5..NET API与COM交互操作7 R, r1 Y& w( c/ a
    在目前的.NET API中,其功能与传统的ObjectARX相比有所不及,有相当的ObjectARX函数目前还没有封装到.NET API中,如GetPoint等。但可以通过COM方式使用ActiveX来弥补.NET API的不足。# b' H3 W6 P8 `4 C% J5 d
增加了COM引用后,程序就可以使用许多VBA中的功能了。以AutoCAD ActiveX中的事件为例,以下代码可以为当前工作空间中所有的图元添加Modified事件:( \+ ?) V" D: q8 c7 R( x4 \
Database db = HostApplicationServices.WorkingDatabase;
9 Y5 l- l5 e1 v4 T7 s+ O/ ABlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead);
2 s( B7 m; d( ~- l1 Z" z( f' f& gBlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite);
2 p" ?% V$ ^' w/ R5 ^) htry {, J) P" b/ Z+ v# G8 j& f
AcadObject obj;
4 {/ L& O, g; l* L! _% g2 |//遍历块表记录3 e1 Z# @9 a4 Z  x
foreach (ObjectId objId in btr) {7 h! U( f. U- ]" A5 y% \; H
    //由ObjectId得到ActiveX中的AcadObject对象, `8 g. i" J. t2 B7 H, j
        obj = (AcadObject)((AcadDatabase)db.AcadDatabase).ObjectIdToObject(objId.OldId);
) e+ f" o1 a, o! y# }* l* e1 W    //为obj添加响应Modified事件
% C  t- M, J1 s        obj.Modified += new IAcadObjectEvents_ModifiedEventHandler(obj_Modified);+ p; ?9 S; N$ Y3 D2 x) ~: g
    }$ ]( L9 ^( ^4 b; _) Q
}
+ P6 h0 x: L' g7 ofinally {
6 V% d5 q- Q7 q' y$ p7 m' T+ m    btr.Close();
3 m% x  j; e/ j: V1 J7 c    bt.Close();
5 o, n' _1 V3 _: ?}
% V/ q# C: S7 k  m其中事件响应函数obj_Modified的表示如下所示:
+ |1 d9 `. E% u2 _1 l9 bpublic static void obj_Modified(AcadObject obj) {$ X9 H# Z/ h) X/ I) Z
CommandLinePrompts.Message("object modified!" + obj.ObjectID + "\n");
6 G# d, H2 j* i- n  d* T- G}' c/ x! F. m  {/ R. U# H9 M
二、结论* q  ~/ `  y- L# i5 i
    本文以C#为例,对基于.NET API的AutoCAD二次开发作了较详细的介绍。.NET API在具有ObjectARX强大功能的同时具有VBA使用方便易用的优点,同时具有C++的强大功能,是较为理想的开发工具。但目前.NET API在某些方面还有些不足,但随着其版本的更新、完善,定会成为众多开发人员的首选工具。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-4-9 04:07 , Processed in 0.053336 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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