青华模具培训学校

 找回密码
 注册

QQ登录

只需一步,快速开始

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

NET平台的AutoCAD二次开发

[复制链接]
发表于 2011-2-24 16:23 | 显示全部楼层 |阅读模式
当前AutoCAD的二次开发工具主要有:VisualLisp、VBA和ObjectARX等。其中,VisualLisp与VBA较为简单,特别是VBA,使用方便且开发速度较快,但其功能相比ObjectARX有所不足,尤其是对面向对象的功能支持不好。而ObjectARX基于VC平台,在C++的支持下,其功能非常强大,可以很好地运用各种面向对象技术,但其缺点是发开速度比较慢,同时对开发人员的能力要求较高。 " Q& m- ^0 j- G0 G  s. V! E
    .NET是微软新推出的开发平台,具有众多优点。基于.NET平台对AutoCAD进行二次开发,可充分利用.NET的各种优势,在保证功能强大的前提下大大提高开发速度。
, a8 D* N$ `! W2 e2 A' Q9 m3 R一、基于.NET的开发
$ a3 K+ Z" p5 [! _  u    1..NET API简介
  m3 v. c8 b% ?5 f    在新推出的AutoCAD 2006中,Autodesk为其开发增加了.NET API。.NET API提供了一系列托管的外包类(Managed Wrapper Class),使开发人员可在.NET框架下,使用任何支持.NET的语言,如VB.NET、C# 和Managed C++等对AutoCAD进行二次开发。其优点是完全面向对象,在拥有与C++相匹配的强大功能的同时,具有方便易用的特点,是较理想的AutoCAD二次开发工具。
$ R) U: @& H* @. g3 E, C; N5 ^    2..NET API与传统ObjectARX的主要区别: }8 ^& A- Y% g! y
    .NET API与传统ObjectARX的区别主要源于在.NET环境下开发应用程序与在VC环境下开发应用程序的区别。首先,在VC环境下,程序员需要自己管理内存的申请和释放,而.NET采用了垃圾回收机制,由.NET框架自行判断内存回收的时机并实行回收,从而解决了令C++程序员头痛的内存泄漏问题。也正是由于这个特点,在.NET环境下不能象在C++环境下那样利用析构函数释放其他的资源,需要程序员在程序中显式地释放。在.NET API中,主要通过Dispose来函数进行资源的释放。
8 ~4 E7 [6 r0 @: ], D& U    其次,ObjectARX中的各种反应器(Reactor)在.NET API中由外包类映射为各种事件(Event),可通过定义这些事件的响应函数来响应AutoCAD的各种操作。同时对于错误信息的处理也从函数返回值改变为通常异常来处理,使其更好地兼容.NET。由于VB.NET、C#等语言都是完全面向对象的,没有全局函数的概念,所以.NET API将ObjectARX下的全局函数封装为.NET API下的某些对象或对象的属性,如ObjectARX下与用户交互的系列全局函数被封装为CommandLinePrompt类。" W8 N7 }- U8 P( }3 R+ T
    3.使用.NET API% N+ i3 l3 U4 }
    下面以C#为例,在Microsoft Visual C# 2005 Express Edition Beta平台上,先新建一个Class Library项目,再将AutoCAD2005安装目录下的acdbmgb.dll与acmgb.dll作为引用添加进项目中。这两个文件包含了.NET API中所有的外包类。
0 N4 m( o2 L& R) _3 c% e. t& p0 x    然后在要使用.NET API的类中添加以下语句以引用.NET API的命名空间。需要添加的语句如下:
7 k% h* X, h% Q$ C    using Autodesk.AutoCAD.ApplicationServices;: ?+ ^" v8 B3 `) e7 E9 l/ D6 K4 t
    using Autodesk.AutoCAD.DatabaseServices;' O# m; b' T# W* x' a4 n# Y7 g/ k
    using Autodesk.AutoCAD.Runtime;
5 }3 s4 \$ {( ]; v& z/ F: x    using Autodesk.AutoCAD.Geometry;$ E& I6 O# |" ]/ F6 J% L/ s
    这样就可以利用.NET API进行开发了。以下代码可在AutoCAD注册为一个命令“AddLine”,该命令可在当前工作空间中添加一条起点为(0,0,0),终点(200,200,0)的直线。代码如下:% }; f$ t4 Q  `
    [CommandMethod ("AddLine")]* z, ^, l+ J9 p1 a
    public static void AddLineCmd()
  K1 s# ]! B6 e' R. f; x    {
: U/ B  d( x8 i  Z/ P* |; c  q* \8 O! g    Database db = HostApplicationServices.WorkingDatabase;//获得当前工作空间的数据库
. Y' D8 V' J& e; k    BlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead); //获得块表2 @7 d4 m# n. e( }, D
    BlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite); //获得模型空间的块表记录
3 ]! p3 i- l: \' B% w- g    Line line = new Line(new Point3d(0, 0, 0), new Point3d(200, 200, 0));//创建一条直线, p0 V2 x) c5 E6 f1 `
    try {) E' o, `, I# H( @: }: y
    btr.AppendEntity(line);//将直线添加到模型空间中9 g' I# |% L/ _; l0 Q
    line.Close();//关闭该直线: j5 D8 \) _0 [% K1 Z- q; z
    }
! [$ x9 I6 L' e" O3 q9 z    finally {/ u8 {! u0 a, Q- g- T  Z% P
    btr.Close();//关闭块表记录, e0 l" c* d9 T+ ?& z
    bt.Close();//关闭块表. |4 F; ]) h8 C6 c$ L
    }
& |% E! m2 F1 M% s9 X: k    }  C: [9 Q- I5 [% G: G/ d
    由此可见,上述语句与在VC下的开发非常类似,其过程都是先得到数据库,然后依次打开块表、块表记录,接着添加实体,最后关闭块表、块表记录。值得注意的是finally语句,无论try块中的语句是否发生异常,finally块中的语句都会被执行,从而确保关闭块表和块表记录的操作会被执行。
  `6 G8 }( E0 p  d    写完代码后进行编译,编译完成将得到一个dll文件。在AutoCAD 2006中通过“netload”命令即可选择该dll文件进行加载,加载成功后即可以通过“AddLine”命令执行上述代码。遗憾的是目前的.NET API版本还不支持卸载,若要卸载只能关闭AutoCAD。# F3 _1 v9 q/ J6 G/ N' R( Q
    4..NET API的初始化与清除, Q$ A' m+ ]4 w4 |
    在ObjectARX中,“acrxEntryPoint”函数是ARX程序的载入点,程序的初始化和清除均可在该函数中进行。而在.NET API中则首先需要将初始化代码封装在一个类中,同时该类需要压迫实现/ p, _& O( L5 l6 c4 B5 A+ u7 |
    IExtensionApplication接口。该接口包含Initialize与Terminate两个函数。其中Initialize负责加载程序时的初始化操作,Terminate则负责进行卸载程序时的清除操作。代码如下:/ O  i1 [  j. x- f# Z8 @, j
namespace ARXExample {: X! x) i; M5 g
public class MyARX : IExtensionApplication {' l. }( g- Z7 j' g9 X
……5 _3 j* r4 q" u/ {; ^7 Y
public void Initialize() {  \+ X6 T0 F! S! {$ S" z
//初始化操作
' V' J6 H4 I# @8 V7 p4 `7 L}" Q: K& P) t- U8 _
public void Terminate() {
) t% c$ Q! h/ M2 V2 Q) o      //清除操作# U7 L0 H! k; V" R5 j+ ?. F# o
}
" {# _5 s$ `, z  \' @0 W! G" r2 x, r……
. J$ C, p# |! c# @% g8 x# z1 \& e/ i+ N4 N  T
}
& S$ G4 N# n) B5 K% v# v4 |8 \% i同时,为加快加载速度,可在MyARX.cs的文件头加入以下语句:: R& a8 \: r  T2 k6 j5 {( ^) h
[assembly: ExtensionApplication (typeof (ARXExample.MyARX) ) ]
( w6 c' b3 i2 S" z2 Z[assembly: CommandClass (typeof (ARXExample.MyARX) ) ]2 D, M( v) s; o+ I  V. a0 I( b; g
    这样在加载程序时AutoCAD将直接通过MyARX中的Initialize语句进行初始化,同时注册MyARX中的命令。否则,AutoCAD将搜索dll中所有的类以找到实现IExtensionApplication接口的类进行初始化,如找不到则不进行初始化。同样,通过CommandClass属性,AutoCAD也会直接到MyARX类中搜索要注册的命令。当程序中包含的类数目较多时,通过ExtensionApplication和CommandClass这两个属性可显著地加快程序的加载速度。- F" k9 _# \1 K6 C- P
    5..NET API与COM交互操作
6 g- H7 q3 @+ |5 l. H& h' }; s. k    在目前的.NET API中,其功能与传统的ObjectARX相比有所不及,有相当的ObjectARX函数目前还没有封装到.NET API中,如GetPoint等。但可以通过COM方式使用ActiveX来弥补.NET API的不足。% v# W2 m% F4 |: {3 ?" o
增加了COM引用后,程序就可以使用许多VBA中的功能了。以AutoCAD ActiveX中的事件为例,以下代码可以为当前工作空间中所有的图元添加Modified事件:
/ }) l9 ^8 D3 J% v2 s- ?. }Database db = HostApplicationServices.WorkingDatabase;  q- Q7 a  ]0 y2 y+ L
BlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead);/ B0 p+ X; y+ Q( i+ p
BlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite);
. |7 M+ Q. s+ t) Wtry {
0 F) j4 f$ F; T  r2 DAcadObject obj;
1 W2 P: Q3 o$ Y. s# ?2 G" Q4 ]//遍历块表记录1 e9 ]' O6 n- |# U& M
foreach (ObjectId objId in btr) {
2 r( P) a- O" k    //由ObjectId得到ActiveX中的AcadObject对象: i8 N( O: C. U# s- S
        obj = (AcadObject)((AcadDatabase)db.AcadDatabase).ObjectIdToObject(objId.OldId);. N9 f4 ]9 o2 b
    //为obj添加响应Modified事件2 B- n$ X0 ^& h1 g% H* z+ S$ Y
        obj.Modified += new IAcadObjectEvents_ModifiedEventHandler(obj_Modified);
  M2 {( f* I4 z+ J' F) v; y    }# j& X  O# Y5 \3 h! \! S% Q
}
) d- T  p  J0 }3 l# q5 f/ C, jfinally {) M6 J* p; ~+ Y6 r4 C2 j  A  j( x
    btr.Close();5 S/ G% p& h$ X& V$ P% \% o
    bt.Close();* A: T6 W5 H8 d$ N- W
}% O( \' F! O1 ~
其中事件响应函数obj_Modified的表示如下所示:: I8 f' p  l' [, s% g7 L) B
public static void obj_Modified(AcadObject obj) {
# x8 T# y7 m1 eCommandLinePrompts.Message("object modified!" + obj.ObjectID + "\n");
3 y: {$ D4 c& n4 J6 ~% i}, B% z0 b* N/ w5 A- ?7 Z2 x- _6 J5 [% @
二、结论
4 ^& a! l" ^+ E6 b+ L    本文以C#为例,对基于.NET API的AutoCAD二次开发作了较详细的介绍。.NET API在具有ObjectARX强大功能的同时具有VBA使用方便易用的优点,同时具有C++的强大功能,是较为理想的开发工具。但目前.NET API在某些方面还有些不足,但随着其版本的更新、完善,定会成为众多开发人员的首选工具。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-1-22 21:50 , Processed in 0.053943 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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