第8章 自定义对象

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第8章
本章简介 8
自定义对象
†自定义对象的概念。 †从 AcDbObject 派生对象。 †从 AcDbEntity 派生自定义实体。
学习要点
† 了解自定义对象的概念及其的应用。 † 掌握从 AcDbObject 派生对象。 † 掌握自定义实体的创建方法。
我们在前面介绍了通过扩充数据方式来存储扩充数据,虽然能满足一定的工程需求,但 是由于最终的扩展数据通过结果缓冲链表的方式存储,缺少面向对象特性,在处理的时候比 较繁琐, 我们完成可以定义自己的类来封装数据, 此种情况下我们需要通 AcDbObject 派生数 据库对象;另外,AutoCAD 是一个通用的 CAD 平台,提供如点、线等通用的对象类型,我 们可以针对行业特征派生自己的实体,如定义螺栓类、管道类等,这些派生的实体除了具有 自己的几何形体外,还包含自己所有的一些数据,如管道的管径、材质等属性。本章我们介 绍一下自定义数据库对象的概念和方法,用户可以根据自己的实际需求派生一套面向行业的 对象类型。
8.1
自定义对象
在介绍自定义对象之前, 我们需要对 AutoCAD 中数据库对象的层次关系有所了解了 解,这有助于我们理解后面的实际应操作,AutoCAD 中数据库对象的层次关系如图 8-1 所示。
1
PDF 文件使用 "pdfFactory Pro" 试用版本创建

图 8-1AutoCAD 中数据库对象的层次关系 从图 8-1 我们看出所有的数据库对象类都派生自 AcRxObject,该类是所有数据库对 象的基类,它主要实现对象运行时类型识别机制,提供一些用于类型识别的重要函数,它 提供的函数主要有一下几个: n desc() : 静态成员函数,返回指定类的类描述符对象。 n cast(): 返回指定类型的对象。 n isKindOf(): 用于判断对象是否属于指定类或者派生类。 n isA() :返回未知类对象的类描述符对象。 我们在介绍实体操作的时候讲过如何使用这些函数, 这里我们需要在这里介绍这些函 数的实现机制,从 AcRxObject 派生的类都包含一个相应的类描述符对象,用 AcRxClass 类表示, 它包含了运行使类型的识别信息,AcRxObject 的派生类包含一个指向 AcRxClass 对象的指针(gpDesc),可以通过 AcRxObject::desc()获取这个 AcRxClass 对象指针,而 AcRxClass 对象包含一个指向其父对象 AcRxClass 的指针, 这样构成了类的运行时类层次 表,如图 8-2,我们可以调用 AcRxObject::isKindOf()来判断对象是否是从某个类派生 出来。
图 8-2 行时类层次表 在派生自定义类中要实现运行类的识别信息, 也就是要重载上面提到的 desc()、 isKindOf()
2
PDF 文件使用 "pdfFactory Pro" 试用版本创建

等 函 数 , 这 可 以 通 过 ObjectARX 提 供 的 宏 来 实 现 , 通 过 使 用 类 声 明 宏 ACRX_DECLARE_MEMBERS(CLASS_NAME)可以声明 desc(), cast(), isA()函数,代码如 下: class CMyClass : public AcRxObject { public: ACRX_DECLARE_MEMBERS(CMyClass); …. } 该宏经过编译预处理后被扩展成一下代码: virtual AcRxClass* isA() const; static AcRxClass* gpDesc; static AcRxClass* desc(); static CMyClass * cast(const AcRxObject* inPtr) { return ((inPtr == 0) || !inPtr->isKindOf(CMyClass::desc())) ? 0 : (CMyClass *)inPtr; }; static void rxInit(); 自定义类的静态成员函数 rxInit()用于实现以下初始化操作: n 注册自定义类。 n 创建类的描述对象。 n 将类描述对象添加到类的描述词典中。 在应用程序的初始化函数中必须调用自定义类的静态成员函数 rxInit()来实现自定义类的 初始化,然后调用全局函数 acrxBuildClassHierarchy 把该类添加到 ACRX 运行类层次表中。 另外在应用程序的卸载时需要调用 deleteAcRxClass()把该类从 ACRX 运行类层次表中删 除,应用程序的初始化代码如下: extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt) { switch (msg) { case AcRx::kInitAppMsg: acrxDynamicLinker->unlockApplication(pkt); // 自定义类的初始化 CMyClass::rxInit(); // 把该类添加到 ACRX 运行类层次表中 acrxBuildClassHierarchy(); break; case AcRx::kUnloadAppMsg: // 该类从 ACRX 运行类层次表中删除 deleteAcRxClass(CMyClass::desc()); } return AcRx::kRetOK;
3
PDF 文件使用 "pdfFactory Pro" 试用版本创建

} 所有永久或者临时的图形对象都实现可绘制接口,封装该接口的对象可以通过火绘制 API 完成绘制, 可显示的对象派生自 AcGiDrawable 类, 该类实现图形系统 (GS) 绘制协议。 AcDbObject 类执行文件操作协议, 从该类派生的对象通过重载文件操作函数可以被保存 为 DWG 或 DXF 文件,或者从 DWG 或 DXF 文件读入。 AcDbEntity 类是实体类,派生自 AcDbObject 类,从该类派生的对象除了可以支持文件 操作外,还可以通过重载绘制函数来按照开发者的要求绘制图形。
8.2 从 AcDbObject 派生
从 AcDbObject 类派生的子类可以支持文件操作,即对象可以从 DWG 或者 DXF 文件中 读写, 也就是可以保存到 DWG 或者 DXF 文件中, 要实现文件读写操作派生类必须重载以下 四个函数: Acad::ErrorStatus dwgInFields(AcDbDwgFiler *filer); Acad::ErrorStatus dwgOutFieds(AcDbDwgFiler *filer); Acad::ErrorStatus dxfInFieds(AcDbDxfFiler *filer); Acad::ErrorStatus dxfOutFieds(AcDbDxfFiler *filer); 以上函数的参数是文件操作类 AcDbDwgFiler 或 AcDbDxfFiler 指针,文件操作类是一个 工具类,用于数据库对象的读写读写, ObjectARX 通过枚举类型 AcDb::FilerType 来检查文件 操方式和类型。 例如当调用 AutoCAD 的 SAVE 命令保存文件时,会调用数据库对象的 dwgOutFieds 函 数, 此时使用 kFileFiler 枚举类型; 而当使用 WBLOCK 命令时, 同样调用 dwgOutFieds 函数, 但使用的枚举类型为 kWblockCloneFiler 和 kIdXlateFiler, 如果调用 UNDO 命令取消操作时候, 会调用数据库对象的 dwgInFields 函数,使用的枚举类型是 kUndoFiler。 向文件操作类对象写入数据的过程中,不需要执行错误检查,文件操作类都有一个成员 函数 getFilerStatus()用于返回类的状态,有时候开发者需要检查文件操作类对象的状态。 在 自 定 义 类 中 重 载 文 件 操 作 函 数 时 , 必 须 首 次 调 用 assertReadEnabled() 或 assertWriteEnabled()函数来检查对象处于正确的打开状态, 然后调用自定义类父类的同名函数 来提供对父类数据的重载。 对于 DWG 文件操作函数 dwgInFields 和 dwgOutFieds,必须按照相同的顺序进行数据的 读写操作,否则派生类数据可能发生混乱。 文件操作类对象可以调用成员函数 readItem()和 writeItem()来读写数据,实际上这 两个函数会被所有支持的数据类型重载,另外还可以调用一些指定了数据类型的读写函数, 如 writeInt32 ) 这些函数在被调用时会自动转换参数的数据类型而忽略数据的实际类型, ( 等, 例如自定义类中包含整型数据,则可以调用 readInt32()和 writeInt32()进行相应的读写操 作。 Acad::ErrorStatus CPipeAttribute::dwgOutFields (AcDbDwgFiler *pFiler) const { // assertReadEnabled () ; //----- Save parent class information first. Acad::ErrorStatus es =AcDbObject::dwgOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ;
4
PDF 文件使用 "pdfFactory Pro" 试用版本创建

相关文档
最新文档