在.NET中进行AutoCAD二次开发(C#+ObjectArx)

1.Autodesk官方最新的.net教程(一)(C#版):

修正:

(1)启用对象浏览器方法:

双击托管的类,会自动调用对象浏览器

2)调试环境设置:

应设2项,否则调试程序无法运行:

启动外部程序为:F:/AutoCAD 2007/acad.exe

工作目录为:F:/AutoCAD 2007/UserDataCache/

2.Autodesk官方最新的.net教程(二)(C#版):

   (1)prPointRes = ed.GetPoint(prPointOptions); 前面应加入下列语句:

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

(2).NET AutoCAD 向导生成的项目中调试项目中只加入了外部程序,没有加入工作目录,需手工加入。

(3)加入第2个cad命令的方法:将上一个命令原版拷贝过来,直接修改就可以了。

 3.Autodesk官方最新的.net教程(三)(C#版):

原文中部分变量与类型中没有空格。

 

 

 

Autodesk官方最新的.net教程(一)(C#版)

 

1 Hello World:访问ObjectARX.NET封装类

在这一章中,我们将使用Visual Studio .NET来创建一个新的类库工程。通过这个工程,你可以创建一个能被AutoCAD装载的.NET dll文件。这个dll文件会向AutoCAD加入一个名为“HelloWorld”的新命令。当用户运行这个命令后,在AutoCAD 命令行上将显示“Hello World”文本。

1) 启动Visual Studio.NET,选择文件>新建>工程”(File> New> Project)。在新建工程对话框中选择工程类型为”Visual C#工程,然后选择类库模板,在工程名字框中输入”Lab1”,然后选择工程存放的位置。点击确定按钮来创建工程。

2) 在工程的Class1.cs文件中,一个公有类“Class1”已经被系统自动创建了。接下来向这个类加入命令。要加入命令,你必须使用AutoCAD .NET托管封装类。这些托管封装类包含在两个托管模块中。要加入对这两个托管模块的引用,请用鼠标右键单击引用然后选择添加引用。在弹出的添加引用对话框中选择浏览。在选择组件对话框中,选择AutoCAD 2006的安装目录(这里假定为C:/Program Files/AutoCAD 2006/),在这个目录下找到“acdbmgd.dll”然后选择并打开它。再一次选择浏览,在AutoCAD 2006的安装目录下找到“acmgd.dll”并打开它。当这两个组件被加入后,请单击添加引用对话框中的确定按钮。正如它们的名字所表示的,acdbmgd.dll包含ObjectDBX托管类,而acmgd.dll包含AutoCAD托管类。

3) 使用对象浏览器(Visual Studio.NET查看>其它窗口>对象浏览器菜单项)来浏览加入的两个托管模块所提供的类。请展开“AutoCAD .NET Managed Wrapper”对象(在对象浏览器中显示为acmgd),在整个教程中我们将使用这个对象中的类。在本章中,我们将使用 “Autodesk.AutoCAD.EditorInput.Editor”类的一个实例来在AutoCAD命令行中显示文本。请再展开“ObjectDBX .NET Managed Wrapper” 对象(在对象浏览器中显示为acdbmgd),这个对象中的类将被用来访问和编辑AutoCAD图形中的实体(这部分内容将在以后的章节中介绍)。

4) 引用了ObjectARX .NET 封装类后,我们就可以导入它们。在Class1类的声明语句(位于Class1.cs文件的顶部的)之前,导入ApplicationServices, EditorInput Runtime命名空间。

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

5) 接下来在类Class1中加入命令。要加入能在AutoCAD 中调用的命令,你必须使用“CommandMethod”属性。这个属性由Runtime命名空间提供。在类Class1中加入下列属性和函数。

[CommandMethod("HelloWorld")] 

 public void HelloWorld()

{

}

6) “HelloWorld”命令在AutoCAD中运行的时候,上面定义的HelloWorld函数就会被调用。在这个函数中,一个Editor类的实例将被创建。Editor类拥有访问AutoCAD命令行的相关方法,它还包括选择对象和其它一些重要的功能。AutoCAD当前活动文档的Editor对象可以使用Application类来访问。当Editor对象被创建后,你可以使用它的WriteMessage方法在命令行中显示“Hello World”文本。在HelloWorld函数中加入以下代码:

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

ed.WriteMessage("Hello World");

7) 要在AutoCAD中调试这个程序,你可以让Visual Studio.NET启动一个AutoCAD进程。在解决方案管理器中右键单击“Lab1”,然后选择属性。在Lab1的属性页对话框中,选择配置属性>调试。在启动项中,选择调试模式程序,在启动程序的右边单击省略号按钮然后选择AutoCAD 2006安装目录下的acad.exe。设置好以后,按F5来启动一个AutoCAD进程。这样就会编译你的程序然后自动启动AutoCAD,而当编译后有错误的时候就会停止。请修正你可能碰到的任何错误。

8) “NETLOAD”命令被用来装载托管程序。在AutoCAD命令行中输入NETLOAD,会出现选择.NET组件的对话框。选择上面生成的“lab1.dll”然后打开它。

9) 在命令行中输入“HellowWorld”。如果一切顺利的话,命令行中将显示“Hello World”文本。切换到Visual Studio.NET,在ed.WriteMessage(“Hello World”);语句处加入一个断点。在AutoCAD中再次运行HelloWorld命令,你会注意到你可以跟踪代码的运行。Visul Studio.NET调试菜单有好几项可以用来跟踪程序的运行。

如果有时间的话,请浏览一下CommandMethod属性。你会发现它有七种不同的形式。在上面的例子中,我们使用了最简单的形式,它只有一个输入参数(命令的名字)。你可以使用其它的形式来控制命令的工作方式,例如你可以确定命令组的名字、全局和局部名字、命令标识(命令如何来运行)等。

 

Autodesk官方最新的.NET教程(二)(C#版)

2章  .NET AutoCAD 向导及Editor类

        在第一章中,我们使用的是类库模板,这样就不得不手工加入acdbmdg. dll 和acmgd.dll这两个引用。在这一章中,我们将使用AutoCAD托管C#应用程序向导来创建.NET工程,它会自动加入以上两个引用。在开始本章之前,你首先得安装ObjectARX向导(ObjectARX2006开发包的/utils/ObjARXWiz/ArxWizards.msi)。

 

1)    启动Visual Studio .NET,选择”文件>新建>工程”(File> New> Project)。在新建工程对话框中选择工程类型为”Visual C#工程”,然后选择“AutoCAD Managed CS Project Application”模板。在工程名字框中输入”Lab2”,然后选择工程存放的位置。点击确定按钮,“AutoCAD Managed CSharp Application Wizard”对话框将会出现。因为我们不需要使用非托管代码,所以不要选择“Enable Unmanaged Debugging”项。“Registered Developer Symbol”将会使用你在安装ObjectARX向导时输入的值。单击”finish”按钮来创建工程。

2)    下面来看一下向导生成的工程。在解决方案浏览器中,你会看到acdbmgd 和 acmgd已经被引用了。在Class.cs文件中,“Autodesk.AutoCAD.Runtime”命名空间已被导入,工程使用“Registered Developer Symbol”的名字来命名缺省的公有类。向导还为类加入了一个CommandMethod属性和一个函数,它们用于AutoCAD命令。

3)    在前一章中,我们使用一个“Autodesk.AutoCAD.EditorInput.Editor”类的实例对象在AutoCAD命令行上输出文本。在这一章中,我们将使用这个类来提示用户在AutoCAD图形中选择一个点,然后将用户选择的点的x,y,z值显示出来。和前一章一样,请导入Autodesk.AutoCAD.ApplicationServices 和 Autodesk.AutoCAD.EditorInput命名空间。

4)    把向导生成的CommandMethod属性的值改为有意义一些的名字如“selectPoint”(函数的名字可以不用修改)。PromptPointOptions类用来设置提示字符串和其它的一些控制提示的选项。这个类的一个实例作为参数被传入到Editor.GetPoint方法。在函数的开始,实例化这个类,设置字符串参数为“Select a point”。因为 Editor.GetPoint方法会返回一个PromptPointResult类的实例对象,所以我们也要把它实例化。

 

PromptPointOptions prPointOptions =

new PromptPointOptions("Select a point");

PromptPointResult prPointRes;

 

5)    接下来实例化一个Editor类的对象并使用参数为PromptPointOptions对象的GetPoint方法。用GetPoint方法的返回值来给上面声明的PromptPointResult对象赋值。赋值好以后,我们可以测试PromptPointResult对象的状态,如果不是OK就返回。

 

prPointRes = ed.GetPoint(prPointOptions);

       if (prPointRes.Status != PromptStatus.OK)

       {

           ed.WriteMessage("Error");

}

 

6)    如果PromptPointResult对象返回了一个有效的点,我们就可以使用WriteMessage方法把结果输出到命令行。PromptPointResult.Value的ToString方法使输出非常容易:

 

ed.WriteMessage("You selected point "

 prPointRes.Value.ToString)

 

7)    F5来运行一个调试AutoCAD的进程。(注意:向导已经设置好用acad.exe来调试)在AutoCAD命令行中输入NETLOAD,选择Lab2.dll并打开。在命令行中输入你起的命令名字(selectPoint)。在选择点的提示下,单击图形中的任一点。如果一切正常的话,你可以在命令行中看到你所选的点的坐标值。在Class.cs文件的“ed.WriteMessage("Error");”行加入断点,然后再次运行selectPoint命令。这一次,在选择点的提示下按ESC键而不是选择一个点。PromptPointResult对象的状态就不是OK了,所以上面代码中的if语句就会被执行,“ed.WriteMessage("Error")”;语句就会被调用。

8)    接下来我们将加入另外一个命令,它可以获取两个点之间的距离。向导没有添加命令的功能,所以我们必须手工添加。在Class.cs文件的选择点的函数(getPoint)下面添加一个名为getDistance的新命令。加入命令的方法请参考上一章的内容或本章的源代码,这里就不列出了。使用CommandMethod属性并使字符串参数为“getdistance”或其它类似的名字。在命令的函数中使用PromptDistanceOptions代替PromptPointOptions。当然GetDistance方法的返回值是一个PromptDoubleResult类的实例对象,所以请用PromptDoubleResult来代替PromptPointResult:

 

PromptDistanceOptions prDistOptions = new    

     PromptDistanceOptions("Find distance, select first point:");

          PromptDoubleResult prDistRes;

prDistRes = ed.GetDistance(prDistOptions);

 

9)       和前面的命令一样,也可以测试PromptDoubleResult的状态,然后用WriteMessage方法在命令行中显示值。

 

if (prDistRes.Status != PromptStatus.OK)

         {

             ed.WriteMessage("Error");

         }

      else

         {

ed.WriteMessage("The distance is: " + prDistRes.Value.ToString());

   

  }

 

 

Autodesk官方最新的.NET教程(三)(C#版)

 

3   数据库基础创建我们自己的Employee 对象

打开Lab3文件夹下的Lab3工程文件,或或接着Lab2的代码。

在这一章中,我们将创建一个‘Employee 对象(包括一个圆,一个椭圆和一个多行文本对象),这个对象属于一个自定义的EmployeeBlock’块(这个块驻留在‘EmployeeLayer’层,当在模型空间插入这个块的时候,‘EmployeeLayer’层就会拥有这个块的一个块索引)。本章的每一个步骤中的代码都可以运行,这样做的目的可以使你更清楚地知道每一部分代码完成的功能。第一步将简要说明一下如何在模型空间创建一个圆。

 

 

这一章的重点是在AutoCAD中访问数据库的基础。主要内容包括事务处理(Transaction)、对象IdObjectId)、符号表(symboltables,如块表BlockTable和层表LayerTable)以及对象引用。使用的其它一些对象如颜色Color、三维点Point3d和三维向量Vector3d,都和各自的步骤有关,但重点应该放在数据库基础上。

1)    创建一个名为‘CREATE’的命令,它调用函数CreateEmployee()。这个函数用来在模型空间(MODELSPACE)的(10100)点处创建一个半径为2.0的圆:

         [CommandMethod("test")]
        static public void voidcreateCircle()

        {
//
首先声明我们要使用的对象
            Circle circle; //
这个是我们要加入到模型空间的圆
            BlockTableRecord btr; //
要加入圆,我们必须打开模型空间
            BlockTable bt; //
要打开模型空间,我们必须通过块表(BlockTable)来访问它
//
我们使用一个名为‘Transaction’的对象,把函数中有关数据库的操作封装起来
            Transaction trans;
//
使用TransactionManagerStartTransaction()成员来开始事务处理
            trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction();
//
现在创建圆……请仔细看这些参数——注意创建Point3d对象的‘New’Vector3d的静态成员ZAxis
            circle = new Circle(new Point3d(10, 10, 0), Vector3d.ZAxis, 2);
            bt = (BlockTable) trans.GetObject(HostApplicationServices.WorkingDatabase.BlockTableId, OpenMode.ForRead);
//
使用当前的空间Id来获取块表记录——注意我们是打开它用来写入
            btr =(BlockTableRecord)trans.GetObject(HostApplicationServices.WorkingDatabase.CurrentSpaceId, OpenMode.ForWrite);
//
现在使用btr对象来加入圆
            btr.AppendEntity(circle);
            trans.AddNewlyCreatedDBObject(circle, true); //
并确定事务处理知道要加入圆!
//
一旦完成以上操作,我们就提交事务处理,这样以上所做的改变就被保存了……
            trans.Commit();
//…
然后销毁事务处理,因为我们已经完成了相关的操作(事务处理不是数据库驻留对象,可以销毁)
            trans.Dispose();
        }

 

请仔细阅读一下上面的代码块的结构,可以通过注释来了解相关的细节。

注意:要编译代码,你必须导入Autodesk.AutoCAD.DatabaseServices Autodesk.AutoCAD.Geometry命名空间

运行这个函数来看看它是否可行。应该会在图形中创建一个在(10,10,0)处的半径为2.0的白色的圆。

 

2)    我们可以减少代码的输入量,这可以通过声明一个Database变量代替HostApplicationServices.WorkingDatabase来实现:

           Database db =HostApplicationServices.WorkingDatabase;

 

使用这个变量来代替在代码中出现的HostApplicationServices.WorkingDatabase

 

3)    在上面的代码中,我们没有使用任何异常处理,而异常处理对一个正确的.NET应用程序来说是非常重要的。我们要养成使用异常处理的好习惯,所以让我们在这个函数中加入try-catch-finally

4)    为了使代码紧凑,我们可以把许多变量的声明和初始化放在同一个语句中。现在,你的代码看起来应该是这样的:

 

[CommandMethod("CREATE")]

        public void CREATEEMPLOYEE()
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            Transaction trans = db.TransactionManager.StartTransaction();
            try
            {
                Circle circle = new Circle(new Point3d(10, 10, 0), Vector3d.ZAxis, 2);
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)trans.GetObject(HostApplicationServices.WorkingDatabase.CurrentSpaceId, OpenMode.ForWrite);
                btr.AppendEntity(circle);
                trans.AddNewlyCreatedDBObject(circle, true);
                trans.Commit();
            }
            catch
            {
                ed.WriteMessage("Error");
            }
            finally
            {
                trans.Dispose();
            }
        }

 

 

运行你的代码来进行测试……

上面的catch块只显示一个错误信息。实际的清理工作是在finally块中进行的。这样做的理由是如果在事务处理被提交(Commit())之前,Dispose()被调用的话,事务处理会被 销毁。我们认为如果在trans.Commit()之前出现任何错误的话,你应该销毁事务处理(因为Commit将永远不会被调用)。如果在Dispose()之前调用了Commit(),也就是说没有任何错误发生,那么事务处理将会被提交给数据库。

所以基于上面的分析,Catch块其实并不是必须的,因为它只用来通知用户程序出现了一个错误。它将在下面的代码中被去掉。

5)    现在让我们在Employee加入剩下的部分:椭圆和多行文本的实例。

       多行文本实体:

              中心点应该与圆心的创建一样:

                     (建议:创建一个名为‘center’而值为10,10,0Point3d变量来表示中心点)

              多行文本的内容可以是你的名字。

       椭圆(提示:你可以先看一下Ellipse的构造函数)

              法向量应该沿着Z轴(请查看Vector3d类型)

              主轴设为Vector3d(3,0,0)

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值