分类: C/C++
2008-09-06 21:58:00
Autodesk公司的AutoCAD软件广泛地应用于设计领域。AutoCAD作为强大而专业的工程绘图软件,近几年来在工程地质制图方面也得到了广泛应用,如钻孔柱状图、剖面图等。但由于CAD本身的原因以及地质图件的特殊性,完全依赖CAD而不借助第三方软件或对CAD进行二次开发,实现地质图件的计算机化也是一件非常困难的事情。好在CAD是一个灵活而又开放的系统,它提供了许多开放式的接口,允许用户通过这些接口对CAD进行二次开发,以满足不同用户的需要。
在AutoCAD R14以前的版本中,最常用的开发工具是AutoLisp和ADS,这两种开发工具都不适应当前可视化编程的需要。幸运的是,在AutoCAD R14版本中,Autodesk公司在AutoCAD中加入了ActiveX自动化服务功能(ActiveX Automation server capabilities),使得用户可以通过可视化编程工具,如Visual Basic(以下简称VB)、Delphi等对AutoCAD进行二次开发,不但提高了工作效率,也满足了不同专业的需要。最近我院开发了“工程地质CAD绘图系统”软件,荣获本单位优秀软件三等奖。该系统我们以AutoCAD R14为平台,VB为开发工具,应用ActiveX技术对AutoCAD进行了二次开发。本文简略地说明AutoCAD中的ActiveX对象模型结构及对模型对象的编程引用。
1 AutoCAD中的ActiveX对象模型
AutoCAD ActiveX提供了一种机制,或者说是一种方法,可以供开发者通过编程手段来操纵AutoCAD。ActiveX是由一系列的对象,按一定的层次结构组成的,每一个对象都代表了AutoCAD中的一个明确的功能。每一个对象本身包含着自己的属性和方法,通过方法可以实现对象的一些操作,如控制CAD的启动,打开一个文档,一条直线的生成。而属性则是对象自己本身所具有的一些性质,如一个文本对象,它的属性有文本的高度,宽度、文本的颜色,所在层等。应用程序正是通过对AutoCAD暴露的各级对象的方法和属性的引用控制AutoCAD工作的。
理解AutoCAD的对象模型是实现编程的基础。AutoCAD以层次结构组织对象(对象模型图可以参考R14版本中的帮助文件)。在顶层是Application对象(即AutoCAD 本身),其他对象均为Application对象的子对象。在Application对象下面是Preferences(优先设置)和Document(文档)对象,通过Preferences对象可以对AutoCAD Tools>Preferences菜单项中的几乎每一个选项进行访问和修改,以获取或改变AutoCAD的优先设置。Document对象是控制AutoCAD图形文件的直接对象,它代表某一个装入的CAD图形文件(一般设为当前激活的文件)。Document对象下面有Model Space(模型空间)和Paper Space(图纸空间)对象及Blocks(块)、Layers (层)、Plot(出图)、Selectionsets(选择集)、 views(视图)、 utility(功能)等一系列对象(集合),其含义与AutoCAD中相似。Model Space是当前图形文件中图形实体,如直线、圆、多义线等的集合,每个实体即是一个对象,可通过属性和方法改变实体或生成新实体。对非图形实体,如层(layer)、线形(line type)等的访问则通过访问Document对象下面的相应的集合类型的子对象,如Layers 、LineTypes等来实现。集合类型的对象可以使用VB中所有的集合操作方法。Plot对象提供了访问Plot对话框中各选项的桥梁,使应用程序具有用不同方式控制AutoCAD出图的能力。Utility对象使用户在AutoCAD命令行与CAD交互成为可能,通过它可以处理整型、浮点型、字符型等用户输入,还可以接受点(Point)或角(Angle)等AutoCAD的特殊量。以上简要地说明了CAD中的对象及其层次结构关系,有了这些理解对编程控制CAD就不难了。
2 AutoCAD对象的使用
2.1 AutoCAD application对象
如前所述,Application对象位于AutoCAD层次对象结构的顶层,它代表AutoCAD自身,所有的应用程序必须从Appliction对象的建立开始。
Dim aCADapp As Object '建立Application对象
Dim aCADdoc As Object '建立Document对象
Dim mospace As Object '建立Model Space 对象
On Error Resume Next
Set aCADapp = GetObject(, "autoCAD.application")
If Err Then
Err.Clear
Set aCADapp = CreateObject("autoCAD.application") ‘
If Err Then
MsgBox Err.Description
Exit Sub
End If
End If
Set aCADDoc = aCADApp.ActiveDocument
上一语句是设aCADdoc为当前图形文档。
Set aCADutil = aCADDoc.Utility '与用户交互
aCADApp.Visible = True ‘此语句是使CAD可见。
Set mospace = aCADdoc.ModelSpace 设置mospace为当前图形文档的模型空间。
以上程序段是应用程序初始化的过程,即选择性地启动AutoCAD。如果CAD已经启动则跳此过程,反之则初始化启动CAD。一般对AutoCAD图形文档的操作,主要是与Application、Document、Utility和Model Space等对象发生关系。
Application对象是一系列对象的父对象,可以通过它的属性设置来改变AutoCAD的窗口设置。如下面代码:
aCADapp.Top=100 '设置AutoCAD窗口的位置
aCADapp.Left=200
aCADapp.Height=1000 '调整AutoCAD窗口的大小
aCADapp.Width=800
2.2 Document对象
(1) 对文件的操作
Document对象提供了大多数AutoCAD软件中有关文件的功能,可以通过它在AutoCAD中新建(New)、打开(Open)、输出(Export)、输入(Import)等文件功能操作。编程时先把Document对象设为Application对象的 ActiveDocument属性,以返回当前活动的图形文档。例:
Set aCADdoc=Application.ActiveDocument
请看下面的例子对文件的操作:
Dim Docname As String
Docname = "e:\temp\zk01.dwg"
If Dir(docname) <> "" Then
aCADdoc.Open docname '如果文件存在则打开CAD文件
Else
aCADdoc.new("aCAD") '若不存在则以aCAD.dwt为模板建立一个新文件。
End If
把当前文档存盘则可以用下面的语句:
if docname<>"" then 'docname不存在时存盘
aCADdoc.save
else
msgbox “该文件已经存在!” '提示该文件已经存在
end if
Document对象还提供了两个非常有用的方法—SetVariable 和 GetVariable,通过它们可以得到(用GetVariable)或改变(用SetVariable )AutoCAD的系统变量。
如语句:
aCADdoc.SetVariable "Orthomode", 1 '打开正交模式
dim CADver As String
CADver=aCADdoc.Getvariable("ACADver") '获取AutoCAD的版本号
(2) 对图形实体的操作
图形实体是指所有CAD的图元物体,如点(point)、线(Line)、圆(Circle)、弧(Arc)、文字(Text)等,它们包含于ModelSpace和PaperSpace集合对象中。对实体的操作总要从这两个集合开始,向下查找相应实体所属的方法或属性。而图形实体的操作包括实体的生成、编辑和查询。 ModelSpace与PaperSpace是所有图形实体的集合,因此要取得图中的某一实体,一般采用遍历查找的方法,下面代码是CAD图形实体的生成、编辑实体或查询。
生成一条直线的代码:
Dim lineobj As Object
Dim pt1(0 To 2) As Double
Dim pt2(0 to 2) as double
Pt1(0)=0#
Pt1(1)=0#
Pt1(2)=0#
Pt2(0)=100#
Pt2(1)=50#
Pt2(2)=0#
SetlineObj = moSpace.Addline(pt1,pt2)
‘画从坐标点pt1至坐标点pt2的直线
改变这条直线的颜色(假设直线实体句柄为"4C")的代码:
Dim tobj As object
Set tobj=aCADdoc.HandletoObject("4C")
tobj.Color=acRed ‘
tobj.Update
查询图形文件中所有实体的实体名、实体句柄、颜色、所在层、线形等参数,如下面的代码所示:
Dim ent As Object
Dim msgStr, NL As String
Dim I as Integer
NL = Chr(13) & Chr(10) ‘回车与换行
I=1
For Each ent in mospace
msgStr = "第" & Format(I) & "个实体信息" & NL & NL
msgStr = msgStr & "实体名: " & ent.EntityName & NL
msgStr = msgStr & "所在层: " & ent.Layer & NL
msgStr = msgStr & "颜色: " & Str(ent.Color) & NL
msgStr = msgStr & "线形: " & ent.Linetype & NL
msgStr = msgStr & "句柄: " & ent.Handle & NL
MsgBox msgStr
I=I+1
Next
2.3 人机交互
Utility对象提供了用户和CAD在命令行进行交互的途径,可以让用户在CAD的的命令行中输入数字、字符串及角度、点坐标等数据。下面说明如何应用Utility交互替代AutoCAD命令中的提示:
Dim tlpt As Variant
Dim pt(0 to 2) as double
Dim txtobj as object
tlpt = aCADutil.GetPoint(, "请选取""图例""字插入点:")
pt(0)=tlpt(0)
pt(1)=tlpt(1)
pt(2)=tlpt(2)
set txtobj=aCADdoc.mospace.addtext(“图例”,pt,0.5)
运行这段代码会在CAD的命令行里出现“请选取""图例""字插入点:”,这时在画图区域选择任一点,按下鼠标左键,则会在我们所选定的插入点写出“图例”这两个字。
2.4 对非图形对象的操作
非图形对象如图层(Layers)、视图(Viewports)、坐标系(UCSs)、块(Blocks)等与图形实体集合ModelSpace、PaperSpace同是Document对象的子对象,它们本身既是对象,又是对象的集合,如Layers是当前打开图形中所有层的集合。使用Add方法来建立新层,可以遍历所有层。通过改变其属性可以达到关闭(Off)、冻结层(Freeze)的目的。
如下面的代码是把层名为"zk"的层冻结,打开层名为"water"的层,并设为当前层:
Dim tlayer as Object
For Each tlayer In aCADdoc.Layers
If tlayer.Name = "zk" Then
tlayer.Freeze = acTrue
Else If tlayer.Name="water" Then
tlayer.LayerOn = acTrue
Set aCADdoc.ActiveLayer = tlayer
End If
Next
2.5对选择集的操作
选择集在CAD应用中占有十分重要的地位,对编程者而言,并不清楚图中包含有哪些实体,只有通过用户的选择或通过过滤条件把所需的实体加入选择集中,再对选择集中的实体进行操作。下面的代码把图形中所有在层"zk"上的直线显示出来。
Dim actualCode(3) As String
Dim actualValue(3) As String
Dim groupcode As Variant
Dim groupValue As Variant
Dim extminpt(2) As Double
Dim extmaxpt(2) As Double
Dim tsset As Object
Dim tobj As Object
actualCode(0) = -4
actualValue(0) = "
actualCode(1) = 8 '保证 Layer是"zk"
actualValue(1) = "zk"
actualCode(2) = 100
actualValue(2) = "AcDbLine" '所选实体为直线
actualCode(3) = -4
actualValue(3) = "AND>"
extminpt(0) = 0
extminpt(1) = 0
extminpt(2) = 0
extmaxpt(0) = 800
extmaxpt(1) = 400
extmaxpt(2) = 0
groupcode = actualCode
groupValue = actualValue
Set tsset = aCADdoc.SelectionSets.Add("SS2")
tsset.Select acSelectionSetAll, extminpt, extmaxpt,_ groupcode, groupValue
For Each tobj In tsset
tobj.HighLight(True)
Next
上述变量中groupcode是组码,groupValue是组码下的值。只要找出相应的组码及组码的值,配合条件(And Or Not等,组码为-4)的使用,便可以构造出任意的过滤器,迅速获取所需实体的集合。
国内有不少介绍ActiveX编程及AutoCAD的资料,目前最容易得到的资料就是Autodesk公司编写的随机帮助文件。帮助文件全是英文的,其中有一章“ActiveX Automation",有全部对象的方法、属性说明。随着AutoCAD2000及AutoCAD2002甚至是AutoCAD2004版本的推出,ActiveX模型对象和CAD的二次开发手段都得到了极大的丰富。以上只是我们用VB,在CAD平台上二次开发的一些体会,由于成文时间仓促,错误和不足在所难免,望不吝指正。