使用ObjectARX宏管理继承于ObjectARX的自定义类。宏允许自定义类参与AcRxObject运行时类型标识机制。
为了便于开发,应该在单独的ObjectDBX中声明和实现自定义类。对象启用器应该包含应用程序的数据库部分,包括本节中描述的AcRxObject宏、其他ObjectARX类覆盖的函数以及特定于自定义类的函数。因为它是一个ObjectDBX模块,所以对象支持器可能不使用AutoCAD或任何其他特定于AutoCAD主机应用程序的API。
ObjectARX提供了一组宏,在rxboiler.h文件中声明,它帮助您创建从AcRxObject派生的新类。如果您不使用ObjectARX宏来定义新类,该类将继承其最直接注册对象的父类的运行时标识。
AcDbDimension
AcDbSymbolTable, AcDbSymbolTableRecord, and all classes derived from them
AcDbBlockBegin
AcDbBlockEnd
AcDbSequenceEnd
AcDb2dPolyline
AcDb2dVertex
AcDb3dPolyline
AcDb3dPolylineVertex
AcDbPolygonMesh
AcDbPolygonMeshVertex
AcDbPolyFaceMesh
AcDbPolyFaceMeshVertex
AcDbFaceRecord
AcDbViewport
AcDbMInsertBlock
AcDbVertex
在ObjectARX的层次,从AcRxObject继承的每个类都有相应的类描述符对象,它是AcRxClass的一个实例,它保存用于运行时类型标识的信息。类描述符对象 gpDesc,类的静态成员,例如 AcDbEllipse::gpDesc。类描述符对象是在初始化时创建的。当类在ObjectARX中注册并添加到系统级字典时,acrxClassDictionary。这里描述的宏有助于声明和实现与运行时标识和初始化功能相关的某些功能。desc(),cast(),isKindOf()和isA()
AcRxClass* isA() const;
当您已经知道对象是什么类时,可以使用desc()函数来获得类描述符对象:
static AcRxClass* desc();
例子1
// 当前实体
AcDbEntity* curEntity = somehowGetAndOpenAnEntity();
// 判读当前实体是不是一个AcDbEllipse的实例或是继承于AcDbEllipse的子类
if (curEntity->isKindOf(AcDbEllipse::desc())) {
// Got some kind of AcDbEllipse instance.
}
例子2
// 另一种方式来查找给出的实体是否是一个AcDbEllipse的实例或是AcDbEllipse的子类
AcDbEllipse* ellipseEntity = AcDbEllipse::cast(curEntity);
if (ellipseEntity != NULL) {
// Got some kind of AcDbEllipse instance.
}
例子3
// 判断当前实体是不是AcDbEllipse的实例而非AcDbEllipse的子类的实例。
if (curEntity->isA() == AcDbEllipse::desc()) {
// Got an AcDbEllipse, no more, no less.
使用ACRX_DECLARE_MEMBERS(CLASS_NAME)声明 desc(),cast()和isA()函数
class myClass : public AcRxObject
{
public:
ACRX_DECLARE_MEMBERS(myClass);
...
};
// 声明宏
ACRX_DECLARE_MEMBERS(AsdkPoly);
// 展开如下
virtual AcRxClass* isA() const;
static AcRxClass* gpDesc;
static AcRxClass* desc();
static AsdkPoly* cast(const AcRxObject* inPtr)
{
return ((inPtr == 0)
|| !inPtr->isKindOf(AsdkPoly::desc()))
? 0 : (AsdkPoly*)inPtr;
};
static void rxInit();
静态rxInit()函数 和静态指针gpDesc与函数isA(),desc()和cast一起定义。
实现自定义类,有以下3中宏:
- ACRX_NO_CONS_DEFINE_MEMBERS(CLASS_NAME, PARENT_CLASS)
用于抽象类和不应实例化的任何其他类
- ACRX_CONS_DEFINE_MEMBERS(CLASS_NAME, PARENT_CLASS, VERNO)
用于可以实例化但不写入文件的临时类。
- ACRX_DXF_DEFINE_MEMBERS(CLASS_NAME, PARENT_CLASS, DWG_VERSION,
MAINTENANCE_VERSION, PROXY_FLAGS, DXF_NAME, APP)
用于可以写入或读取DWG和DXF文件的类。这些宏中的每一个定义如下:
类描述符 AcRxClass
rxInit()
desc()
isA()
以上函数都会被重写
例子:
ACRX_DXF_DEFINE_MEMBERS(AsdkPoly, AcDbCurve, AcDb::kDHL_CURRENT,\
AcDb::kMReleaseCurrent, 0, POLYGON, /*MSG0*/"AutoCAD");
AcRxClass* AsdkPoly::desc()
{
if (AsdkPoly::gpDesc != 0)
return AsdkPoly::gpDesc;
return AsdkPoly::gpDesc =
(AcRxClass*)((AcRxDictionary*)acrxSysRegistry()->
at("ClassDictionary"))->at("AsdkPoly");
}
AcRxClass* AsdkPoly::isA() const
{
return AsdkPoly::desc();
}
AcRxClass* AsdkPoly::gpDesc = 0;
static AcRxObject * makeAsdkPoly()
{
return new AsdkPoly();
}
void AsdkPoly::rxInit()
{
if (AsdkPoly::gpDesc != 0)
return;
AsdkPoly::gpDesc = newAcRxClass("AsdkPoly",
"AsdkCurve", AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
0, &makeAsdkPoly, "POLYGON", "\"AutoCAD\"");
};
如果你想重写自己的rxInit()函数,使用ACRX_DEFINE_MEMBERS()宏,这个宏定义了desc(),cast()和isA(),但是没有定义rxInit函数
每个类的类初始化函数是rxinit(),定义自定义类的应用程序必须在运行时初始化期间调用此函数。
这个功能是自动定义的三个ACRX_xxx_DEFINE_MEMBERS()宏和执行以下任务:
- 注册自定义类
- 生成自定义类的描述对象
- 将类的描述对象放到类字典中
如果您想要定义自己的rxinit()函数,使用ACRX_DEFINE_MEMBERS()宏