ObjectARX 程序设计环境,为开发者使用、用户化和扩充AutoCAD,提供了一个面向对象的C++应用程序设计接口。目前,ObjectARX 功能如下:
1、 访问AutoCAD数据库。
AutoCAD 图是一个储存在数据库中的对象的集合,这些对象不仅表示图形实体,而且表示内部结构,如符号表和词典。ObjectARX为我们的应用程序提供了访问这些数据库结构的能力,我们也可以专用应用程序创建新的数据库对象。
2、 与AutoCAD编辑器通信。
ObjectARX 提供了与AutoCAD编辑器通信的类和成员函数。我们可以用AutoCAD注册命令。该命令可以当作AutoCAD内部命令一样使用。应用程序可以接收和回应发生在AutoCAD内的各种事件。
3、 可以用MFC创建用户界面。
可以使用与AutoCAD共享的动态链结MFC创建ObjectARX应用程序。我们可以使用该库创建标准的GUI。
4、 支持多文档界面(MDI)。
使用ObjectARX,我们可以创建支持AutoCAD多文档界面的应用程序,并且可以保证在Windows环境下创建的应用程序与其他的应用程序正常通信。
5、 创建自定义类。
我们可以用ObjectARX类层次结构中的类创建自己的自定义类,也可以使用ObjectARX 的扩展图形库创建自定义类。
6、 编制复杂应用程序。
ObjectARX支持复杂应用程序的开发,并提供如下特性:通知、事务管理、 深层克隆、引用编辑、协议扩充、代理对象支持。
7、 和其他的程序设计环境通信。
ObjectARX 应用程序可以与其他的程序接口通信。如Visual LISP、ActiveX和COM。通过URL与实体相连接,或者互联网加裁和存储图文件,ObjectARX应用程序也可以和互联网通信。
ObjectARX环境包含下列几组类和函数:
AcRx 用于绑定应用程序及运行时类的注册和标识的类。
AcEd 注册本地AutoCAD命令和AutoACD事件通知的类。
AcDb AutoCAD数据库类。
AcGi 显示AutoACD实体的图形类。
AcGe 公用线性数学和几何学对象应用类。
AcRx库提供了一些系统级类,用于DLL的初始化和链接及运行时类的注册和标识。该库的基类是AcRxObject,它提供如下功能:对象运行时类标识和继承分析、运行时向既有类添加新协议、对象比较测试、对象复制。运行时类型标识是AcRxObject的每个子类都有一个相关的类描述者对象(AcRxClass类型),用于运行时类型的标识。
AcEd库提供定义和注册新的AutoCAD命令的类,新命令的操作性能与AutoCAD内部命令是完全一样的。我们定义的新命令被当作本地命令是因为它们与AutoACD内部命令具有相同的内部结构 (AcEdCommandStack)。AcEd库还提供编辑器反应器和一套与AutoCAD通信的全局函数。注:该库中一个重要的类是AcEditorReactor,它监视AutoCAD编辑器的状态,并当指定事件发生时(如形开始、终止和删除命令)通知应用程序。
AcDb库提供了组成AutoCAD数据库的类。AutoCAD数据库用于存储所有的图形对象和非对象;图形对象称为实体,组成AutoCAD图;非图形对象(如层、线型和字型)也是图形的一部分。同时我们可以使用AcDb库查询和管理AutoCAD实体的实体对象,也可以创建新的数据库对象实例。AutoCAD数据库包含如下主要元素:九个符号表,每个表都拥有唯一的命令符号表条目对象,这些对象表示各种常用的AcDbDatabase对象和数据成员;命名的对象词典(类AcDbDictionary),提供AutoCAD图的目录表。对于新图来说,该目录表包含四个AutoCAD使用的其他词典ID,同时我们的应用程序可以任意向该词典添加其他的对象;一套固定的环境变量,大约200个环境变量,其值上由AutoCAD设置的。
AcGi库提供了用于绘制AutoCAD实体的图形界面,AcDbEntity成员函数worldDraw()、viewportDraw()和saveAs(),及所有标准实体协议部件都使用AcGi库。
AcGe库提供了应用类,如向量和矩阵,用来完成二维和三维几何操作,它还提供基本的几何对象,如点、曲线和表面。AcGe还包含两个主要子集:二维和三维几何类,主要抽象基类分别为AcGeEntity2d和AcGeEntity3d。
ObjectARX目录结构
├─arxlabs 目录存放AutoCAD ARX使用指南。
├─classmap 目录存放AutoCAD图形形式的ObjectARX类层次结构图。
├─docs 目录存放ObjectARX开发者的在线帮助文件,
├─inc ObjectARX头文件。
├─lib ObjectARX库文件。
├─redistrib ObjectARX发行库。
├─samples ObjectARX例子目录。
└─utils ObjectARX的扩展和开发小工具。
这几天都是学习一些AutoCAD和ObjectARX的理论知识,主要目的是和它们混个脸熟,了解它们的过去和现在,学习它们的组织结构,为以后做需求打好基础。
AutoCAD数据库用来存储组成AutoCAD图的对象和实体。基本的数据库对象是实体、符号表和词典。实体是在AutoCAD图内部表示图的一种特殊数据库对象,线、圆、弧、文本、实心体、区域、复合线和椭圆都是实体,用户可以在屏幕上看见实体并能对其进行操作。符号表和词典是用于存储数据库对象的容器。层表(AcDbLayerTable)是符号表之一,它包含层表记录,块表(AcDbBlockTable)也是一个符号表,包含块表记录。所有AutoCAD实体都属于块表记录。词典为存储对象提供了比符号表更加普通的容器。
在AutoCAD中创建的对象被添加到数据库对应的容器对象中,实体被添加到块表的记录中,符号表记录被添加相应的符号表中,所有其他对象被添加到命名对象词典中,或添加到其他对象拥有的对象(拥有其他对象的对象最终属于命名对象词典)中,或添加到扩充词典中。
数据库中包含一套(九个)符号表和一个命名对象词典,表包括块表、层表和线型表。块表最初包含三个记录,一个记录叫做*MODEL_SPACE, 两个图纸空间记录叫作*PAPER_SPACE和*PAPER_SPACE0。这些块表记录表示模型空间和两个预先确定的图纸空间布局。层表最初包含一个0层记录。线型表最初包含CONTINUOUS线型。命名对象词典是当数据库被创建后,命名对象词典就已经包含四个数据库词典:GROUP(组)词典、MLINE类型词典、布局词典和绘图式样名词典,在MLINE类型词典内,总有STANDARD类型。
根据上面的图,在AutoCAD中创建线,并将其添加到模型空间块表记录中需要以下几步:
1、 建立线对象(new AcDbLine)。
2、 通过acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBT)返回当前图中块表对象指针。
3、 然后通过得到的块表以写模式打开模型空间块表记录,同时把块表对象关闭(不用就马上关闭)。
4、 通过块表记录的appendAcDbEntity把新建立的线实体追加到记录中去,同时返回新添加线的实体ID。
5、 关闭块记录和线对象。
同理,Circle也是这样操作的。
今天主要了解AutoCAD中怎么创建实体对象,以及AutoCAD是怎样存放的。由于时间原因,创建层和添加组就不说了,都比较类似的。
今天是学习AutoCAD ObjectARX的第三天,三天来一直在看一本叫《AutoCAD ObjectARX 2000 开发技术指南》技术从书,当今天看ObjectARX 2007开发文档的时候,突然感觉自己都已经看过了,虽然都是英文的。汗,结果两者一样。大汗一把!现在的出版的书… 竟然书上还写着谁谁著。
ObjectARX应用程序是一个动态链接库,它共享AutoCAD的地址空间并且直接调用AutoCAD函数。
创建一个ObjectARX应用程序通常包括以下几个步骤:
1、 创建实现新命令的自定义类。一般都是从ObjectARX提供的类派生出来的自定义类。
2、 决定我们的ObjectARX应用程序将处理哪一个AutoCAD消息。AutoCAD向ObjectARX应用程序发送各种消息,指出在AutoCAD内发生了特定的事件,我们决定应用程序将对哪一个消息作出响应,并触发哪一个操作。
3、 为AutoCAD提供入口。在ObjectARX2007以上的版本中有一默认的入口定义文件(AcRxDefault.def)不用用户再创建。
4、 实现初始化。在ObjectARX应用程序内,我们需要初始化已创建的任何自定义,并且重建ObjectARX运行时类树;如果要添加命令,必须注册在AutoCAD中的命令。
5、 卸载准备。卸载前必须删除所有自定义类和命令。
注册新命令的方法可以用AcEdCommandStack的addCommand的方法和acedDefun还有acedRegFunc的方法。后两咱们以后再说,主要是addCommand注册命令的方法。
AutoCAD命令是由AcEdCommandStack类定义的,按组存储在命令栈中。一般况下用addCommand函数一次添加一个命令,并用removeGroup函数成组的删除命令,也可以用removeCmd函数一次删除一个命令。作为退出前消除工作的一部分,我们应用程序需要删除它注册的所有命令。
addCommand函数的原型声明为:
Acad::ErrorStatus
addCommand(
const char* cmdGroupName,
const char* cmdGlobalName,
const char* cmdLocalName,
Adesk::Int32 commandFlags,
AcRxPtr Addr,
AcEdUIContext *UIContext = NULL,
int fcode=-1);
其中:
cmdGroupName 需要添加命令的组名(用ASCII表示)。如果组不存在,则会自动在添加命令前创建组。
cmdGlobalName 要添加的命令名(用ASCII表示)。该名字是全局的。
cmdLocalName 要添加的命令名(用ASCII表示)。该名字是本地的。
commandFlags 与命令有关的标记,有效值为: ACRX_CMD_TRANSPARENT, ACRX_CMD_MODAL, ACRX_CMD_USEPICKSET, 和 ACRX_CMD_REDRAW。
Addr 当执行命令时,要执行的函数地址。
UiContext AcEdUIContext回调类的输入指针。
fcode 分配给命令的输入整形码。
removeCmd()函数的原型声明为:
virtual Acad::ErrorStatus
AcEdCommandStack::removeCmd( const char * cmdGroupName, const char * cmdGlobalName) = 0;
removeGroup()函数原型声明为:
virtual Acad::ErrorStatus
AcEdCommandStack:: removeGroup ( const char * cmdGroupName);
对于命令的查找顺序可以用AcEdCommandStack::popGroupToTop()函数放在栈顶,AutoCAD会首先查找这个组。
全局与本地命令名的区别是:全局命令名可以在任何语言环境中使用,而本地命令名是用于非英语版AutoCAD命令名的翻译。
透明与模态命令,我的理解是像对话框一样,非模态与模态的区别。
到此,自己完全可以看着文档做一个例子出来了!享受你的成果吧!