青华模具培训学校

 找回密码
 注册

QQ登录

只需一步,快速开始

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

NET平台的AutoCAD二次开发

[复制链接]
发表于 2011-2-24 16:23 | 显示全部楼层 |阅读模式
当前AutoCAD的二次开发工具主要有:VisualLisp、VBA和ObjectARX等。其中,VisualLisp与VBA较为简单,特别是VBA,使用方便且开发速度较快,但其功能相比ObjectARX有所不足,尤其是对面向对象的功能支持不好。而ObjectARX基于VC平台,在C++的支持下,其功能非常强大,可以很好地运用各种面向对象技术,但其缺点是发开速度比较慢,同时对开发人员的能力要求较高。
2 v' f0 d! ?! y: N! V+ `$ N    .NET是微软新推出的开发平台,具有众多优点。基于.NET平台对AutoCAD进行二次开发,可充分利用.NET的各种优势,在保证功能强大的前提下大大提高开发速度。0 f" x* Q1 _1 Y* i6 j3 U
一、基于.NET的开发* P4 I  f  l( D' ]0 F
    1..NET API简介& t5 x) t1 F  i6 D# _
    在新推出的AutoCAD 2006中,Autodesk为其开发增加了.NET API。.NET API提供了一系列托管的外包类(Managed Wrapper Class),使开发人员可在.NET框架下,使用任何支持.NET的语言,如VB.NET、C# 和Managed C++等对AutoCAD进行二次开发。其优点是完全面向对象,在拥有与C++相匹配的强大功能的同时,具有方便易用的特点,是较理想的AutoCAD二次开发工具。9 ^& P3 b3 P; v6 n: [
    2..NET API与传统ObjectARX的主要区别0 G4 T0 [4 {3 L# I: I* |
    .NET API与传统ObjectARX的区别主要源于在.NET环境下开发应用程序与在VC环境下开发应用程序的区别。首先,在VC环境下,程序员需要自己管理内存的申请和释放,而.NET采用了垃圾回收机制,由.NET框架自行判断内存回收的时机并实行回收,从而解决了令C++程序员头痛的内存泄漏问题。也正是由于这个特点,在.NET环境下不能象在C++环境下那样利用析构函数释放其他的资源,需要程序员在程序中显式地释放。在.NET API中,主要通过Dispose来函数进行资源的释放。
7 R9 O$ o) b& w& ~7 e1 D    其次,ObjectARX中的各种反应器(Reactor)在.NET API中由外包类映射为各种事件(Event),可通过定义这些事件的响应函数来响应AutoCAD的各种操作。同时对于错误信息的处理也从函数返回值改变为通常异常来处理,使其更好地兼容.NET。由于VB.NET、C#等语言都是完全面向对象的,没有全局函数的概念,所以.NET API将ObjectARX下的全局函数封装为.NET API下的某些对象或对象的属性,如ObjectARX下与用户交互的系列全局函数被封装为CommandLinePrompt类。
/ o. n8 N& |" ]0 ~( Q& A4 L4 F1 Z    3.使用.NET API& ]: W2 `+ I% {, t
    下面以C#为例,在Microsoft Visual C# 2005 Express Edition Beta平台上,先新建一个Class Library项目,再将AutoCAD2005安装目录下的acdbmgb.dll与acmgb.dll作为引用添加进项目中。这两个文件包含了.NET API中所有的外包类。
6 A( q5 `$ B+ L. y# @1 h  T: l* @    然后在要使用.NET API的类中添加以下语句以引用.NET API的命名空间。需要添加的语句如下:, y9 C7 b/ G; L0 _
    using Autodesk.AutoCAD.ApplicationServices;
7 K/ n6 R8 C* w  C4 F# e    using Autodesk.AutoCAD.DatabaseServices;" v* o/ \! L% H. [6 z5 f- y3 |3 L
    using Autodesk.AutoCAD.Runtime;1 Y5 H7 `9 w% O( r. R" {/ Z) U1 Z
    using Autodesk.AutoCAD.Geometry;
4 A( D: p6 }& i$ Y; z    这样就可以利用.NET API进行开发了。以下代码可在AutoCAD注册为一个命令“AddLine”,该命令可在当前工作空间中添加一条起点为(0,0,0),终点(200,200,0)的直线。代码如下:
+ Q% E$ c# u, m' A( x* C    [CommandMethod ("AddLine")]) B+ Z% Y5 e; }1 r; \4 ^
    public static void AddLineCmd()
, z4 Z: Q* a, ^5 Z4 M" K4 I4 g    {) v- s$ |! X" Z6 x
    Database db = HostApplicationServices.WorkingDatabase;//获得当前工作空间的数据库
, Y2 K* A& D9 m  A$ C    BlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead); //获得块表4 t2 c5 u! c1 U9 N, ]& z- C5 l
    BlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite); //获得模型空间的块表记录; r7 T, h. C" m6 n9 k9 F: d( m
    Line line = new Line(new Point3d(0, 0, 0), new Point3d(200, 200, 0));//创建一条直线+ i' A0 j4 a" U! ?- i) A
    try {9 e* R# h! F, Q4 b# T7 O; j
    btr.AppendEntity(line);//将直线添加到模型空间中1 s4 N) E* F! ~% N3 }
    line.Close();//关闭该直线) _' m! O+ u7 p- Z* p" M' ?
    }) Z$ T- t. o, i- _
    finally {8 j( |: _% c/ c, q3 I
    btr.Close();//关闭块表记录
+ ~  S: L) f- e& N& P; b" h    bt.Close();//关闭块表
5 K5 S$ V% m- _, Z- ?  F    }7 N2 G3 ~( N  ?3 ]" i$ T6 m5 k
    }  ]/ C8 H8 a0 i& \  r* [: e$ y
    由此可见,上述语句与在VC下的开发非常类似,其过程都是先得到数据库,然后依次打开块表、块表记录,接着添加实体,最后关闭块表、块表记录。值得注意的是finally语句,无论try块中的语句是否发生异常,finally块中的语句都会被执行,从而确保关闭块表和块表记录的操作会被执行。/ F# _- V) h* z& A8 P
    写完代码后进行编译,编译完成将得到一个dll文件。在AutoCAD 2006中通过“netload”命令即可选择该dll文件进行加载,加载成功后即可以通过“AddLine”命令执行上述代码。遗憾的是目前的.NET API版本还不支持卸载,若要卸载只能关闭AutoCAD。
9 n9 u" ^+ p, X* ~4 m    4..NET API的初始化与清除
3 F& T2 f+ J' K9 y    在ObjectARX中,“acrxEntryPoint”函数是ARX程序的载入点,程序的初始化和清除均可在该函数中进行。而在.NET API中则首先需要将初始化代码封装在一个类中,同时该类需要压迫实现" a* X' `6 m8 N/ l
    IExtensionApplication接口。该接口包含Initialize与Terminate两个函数。其中Initialize负责加载程序时的初始化操作,Terminate则负责进行卸载程序时的清除操作。代码如下:; [, q  d( e) j' G4 A$ W2 C
namespace ARXExample {4 p6 v) n7 ?: R0 [8 f2 I
public class MyARX : IExtensionApplication {
4 @# ~( U" r8 V1 o$ `3 ~4 S% q: O0 t……2 A. ?# V5 F( J3 G' |) x
public void Initialize() {: r( O% R" g2 P5 w% ]
//初始化操作" Q/ i0 @2 r& ?- d( T6 ^, m5 S
}
* ]% Y# H- _/ m! `! Rpublic void Terminate() {+ r7 t& u/ {  P8 ~. n
      //清除操作
8 n( ]) f' S) D/ H}
: A  J1 ?* \7 c! u) b3 e( }1 p1 `, N; G……
/ v& o' ~4 Z; @( i1 N) I0 H+ }! R/ D7 O3 z! j  W" L7 x9 }
}  B8 P6 ?' T% H$ Z0 P7 _
同时,为加快加载速度,可在MyARX.cs的文件头加入以下语句:' {, j7 g5 y% _" |3 s
[assembly: ExtensionApplication (typeof (ARXExample.MyARX) ) ]
$ @# {6 ]" X; Y8 e# p[assembly: CommandClass (typeof (ARXExample.MyARX) ) ]% n9 O" R2 E" G' V; ]- L9 y
    这样在加载程序时AutoCAD将直接通过MyARX中的Initialize语句进行初始化,同时注册MyARX中的命令。否则,AutoCAD将搜索dll中所有的类以找到实现IExtensionApplication接口的类进行初始化,如找不到则不进行初始化。同样,通过CommandClass属性,AutoCAD也会直接到MyARX类中搜索要注册的命令。当程序中包含的类数目较多时,通过ExtensionApplication和CommandClass这两个属性可显著地加快程序的加载速度。; d; M7 Y+ x) Y4 z1 `
    5..NET API与COM交互操作
6 z2 ]; s4 q: V$ X& N( W7 {8 {    在目前的.NET API中,其功能与传统的ObjectARX相比有所不及,有相当的ObjectARX函数目前还没有封装到.NET API中,如GetPoint等。但可以通过COM方式使用ActiveX来弥补.NET API的不足。' w0 f/ b- ~" F& K  C/ B; O
增加了COM引用后,程序就可以使用许多VBA中的功能了。以AutoCAD ActiveX中的事件为例,以下代码可以为当前工作空间中所有的图元添加Modified事件:
% |! ?* p, B/ ]/ C# bDatabase db = HostApplicationServices.WorkingDatabase;
; H2 b  U" y7 F& g- hBlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead);
; ]; W6 c# A* b5 v+ MBlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite);
* i) t- a) M, _: utry {- O5 _) o9 O6 o, r5 k. {
AcadObject obj;4 r3 C9 p3 U2 m  y& Z. I0 R# `) D
//遍历块表记录
' Z# g) E( ~: n+ _foreach (ObjectId objId in btr) {
0 z  }' ^$ X: x) w. ]2 N* O    //由ObjectId得到ActiveX中的AcadObject对象
& |; O; l, c/ b* V8 @! u5 y# m$ |        obj = (AcadObject)((AcadDatabase)db.AcadDatabase).ObjectIdToObject(objId.OldId);5 m: g* T# C" |: u. v1 u  Q4 S$ |$ R
    //为obj添加响应Modified事件
; o8 `6 M# ?% [  v' e% F- i        obj.Modified += new IAcadObjectEvents_ModifiedEventHandler(obj_Modified);1 w* V( {) u  L- x: \
    }6 a; L  M) V+ F" z
}
- v6 X9 p$ h1 T4 k: `0 ~, ?1 zfinally {
( N1 G6 {2 K( S( H* ?. H    btr.Close();7 u: j( C, H  n
    bt.Close();3 _% r; }4 A* C& j0 \: p
}
5 b0 X% X( S2 m; o其中事件响应函数obj_Modified的表示如下所示:
* P+ j5 K" H* L! i8 x* spublic static void obj_Modified(AcadObject obj) {3 q: _  a1 ~8 ?, u( E0 V$ K
CommandLinePrompts.Message("object modified!" + obj.ObjectID + "\n");2 L% d1 |4 {) t( h. Q
}( }1 q7 ]0 ?. n
二、结论# g9 |2 b* {" q, |# G
    本文以C#为例,对基于.NET API的AutoCAD二次开发作了较详细的介绍。.NET API在具有ObjectARX强大功能的同时具有VBA使用方便易用的优点,同时具有C++的强大功能,是较为理想的开发工具。但目前.NET API在某些方面还有些不足,但随着其版本的更新、完善,定会成为众多开发人员的首选工具。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-9-26 00:28 , Processed in 0.098169 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2023 Discuz! Team.

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