1 说明
在ObjectARX中,除了Xdata以外,还有一种扩展数据——Xrecord。
AcDbXrecord是一种数据存储类,与Xdata类似,但其数据存储量和数据存储类型更多,每个AcDbXrecord对象最多可存储2GB的数据。Xrecord对象的DXF组码范围为1~369。Xrecord存储在一种特殊实体——扩展字典中,而扩展字典可以属于一个实体,这样这个实体就拥有了自定义的扩展数据。
上面提到了扩展字典,为了理解扩展字典,需要讨论字典的生成,这里也涉及到有名对象字典。字典(AcDbDictionary类)与符号表非常类似,相当于是对象的指针的集合,并通唯一的字符串关键字索引(char* text )和对象ID(32-bit )号检索对象。在字典中的对象设计上是指一个对象ID号的关键字字符串。字典中能够包含任意数量的关键字字符串。对象的ID号可能是任何的AcDbObject类或由AcDbObject类派生的类。一个对象只能属于一个扩展字典,但是该扩展字典能够由任何应用程序访问。当一个实体被删除,其扩展字典也将被删除。
2 相关函数
2.1 AcDbObject类
实体AcDbObject类中与扩展字典相关的函数主要有:
createExtensionDictionary()
- 创建一个AcDbDictionary对象,并将其设置为AcDbObject的扩展字典。如果成功,则返回Acad :: eOk。如果扩展字典已经存在,则返回Acad :: eAlreadyInDb。
extensionDictionary()
- 返回实体拥有的扩展字典的objectId, 如果没有,则将返回的objectId设置为AcDbObjectId :: kNull。
releaseExtensionDictionary()
- 如果实体有扩展字典,且不含任何数据,则删除该扩展字典。如果成功,则返回Acad :: eOk;如果扩展字典不为空,则此函数失败并返回Acad :: eContainerNotEmpty。
2.2 AcDbDictionary类
字典AcDbDictionary类中常用函数主要有:
getAt()
- 定义:
Acad::ErrorStatus getAt(
const ACHAR* entryName,
AcDbObject*& entryObj,
AcDb::OpenMode mode
) const;
Acad::ErrorStatus getAt(
const ACHAR* entryName,
AcDbObjectId& entryObj
) const;
- 参数:
entryName —— 要查找的关键字索引;
entryObj —— 返回指向对象的指针;
OpenMode mode——打开对象的模式;有三个可能值,AcDb :: kForRead,AcDb :: kForWrite和AcDb :: kForNotify。 - 作用:在字典中根据关键字索引搜索对象。找到后,指针entryObj指向对象,搜索不区分大小写。
- 返回值:如果成功,则返回Acad :: eOk;如果entryName == NULL或entryName不是有效的关键字索引,则返回Acad :: eInvalidKey; 如果找不到匹配的条目,则返回Acad :: eKeyNotFound。
setAt()
- 定义:
Acad::ErrorStatus setAt(
const ACHAR* srchKey,
AcDbObject* newValue,
AcDbObjectId& retObjId
-
参数:
srchKey —— 要添加到字典中的指向对象的关键字索引;
newValue —— 指向要添加到字典中的对象的指针;
retObjId —— 返回被添加到字典中的对象ID。 -
作用:向字典中添加对象。如果srchKey在字典中不存在,此函数将newValue指定的对象添加到字典中。 如果srchKey已存在,则将原来的对象删除,newValue指向的新对象添加到字典中。
-
返回值:如果成功,则返回Acad :: eOk; 如果srchKey == NULL,返回Acad :: eInvalidKey; 如果newValue == NULL,则为Acad :: eNullEntityPointer。
remove ()
- 定义:
Acad::ErrorStatus remove( AcDbObjectId objId );
Acad::ErrorStatus remove( const ACHAR * key );
Acad::ErrorStatus remove( const ACHAR * key, AcDbObjectId& returnId );
- 参数:
key —— 要从字典中删除的对象的关键字索引;
objId —— 要从字典中删除的对象的ID;
returnId —— 返回字典中被删除的对象的ID。 - 作用:根据关键字索引或对象ID从字典中删除对象。被删除的对象仍在数据库中。
- 返回值:如果成功,则返回Acad :: eOk;如果key == NULL,则返回Acad :: eInvalidKey;如果在字典中找不到key或objId,则返回Acad :: eKeyNotFound。
2.2 AcDbXrecord类
扩展记录AcDbXrecord类中常用函数主要有:
rbChain()
- 定义:
Acad::ErrorStatus rbChain(
resbuf** ppRb,
AcDbDatabase* auxDb = NULL
) const;
-
参数:
ppRb —— 要添加的数据链表的指针的地址; -
作用:获取扩展记录的resbuf数据链表。
-
返回值:如果成功,则返回Acad :: eOk;如果没有足够的内存来创建完整的resbuf数据链表,则返回Acad :: eOutOfMemory。
setFromRbChain()
- 定义:
Acad::ErrorStatus setFromRbChain(
const resbuf& pRb,
AcDbDatabase* auxDb = NULL
);
-
参数:
pRb —— 包含扩展记录的resbuf数据链表; -
作用:将resbuf数据链表添加到扩展记录中,数据链表中的内容由DXF组码指定的数据类型,及对应的数据组成。以下是DXF组代码范围及其代表的数据类型的列表,其中DXF码330~369用于指定对象ID(ads_name)。
DXF码(起) | DXF码(止) | 数据类型 |
---|---|---|
1 | 4 | text |
6 | 9 | text |
10 | 17 | point or vector (3 reals) |
38 | 59 | real |
60 | 79 | 16-bit integer |
90 | 99 | 32-bit integer |
100 | 100 | subclass data marker |
102 | 102 | text |
140 | 149 | real |
170 | 179 | 16-bit integer |
210 | 219 | 3 reals |
270 | 279 | 16-bit integer |
280 | 289 | 8-bit integer |
300 | 309 | text |
310 | 319 | binary chunk |
320 | 329 | handle |
330 | 339 | soft pointer ID |
340 | 349 | hard pointer ID |
350 | 359 | soft owner ID |
360 | 369 | hard owner ID |
- 返回值:如果操作成功,则返回Acad :: eOk;如果数据链表中的对象ID无效,则返回Acad :: eInvalidAdsName。
3 思路
3.1 添加扩展记录
在默认的情况下,实体是没有扩展字典的。因此,要利用扩展字典保存扩展记录,可以按以下步骤:
- 使用createExtensionDictionary()函数为实体建立扩展字典;
- 使用extensionDictionary()函数获取实体的扩展字典;
- 使用setAt()函数为扩展字典添加一个对象,用于存储扩展记录(也可以存储其他类型的对象);
- 使用acutBuildList()函数创建一个数据链表;
- 使用setFromRbChain()函数将创建的数据链表添加到扩展记录中。
这样就完成了为实体添加扩展记录的工作。
3.2 查看扩展记录
查看实体的扩展记录的步骤为:
- 使用extensionDictionary()函数获取实体的扩展字典;
- 然后通过getAt()函数获取指定名称的扩展记录;
- 使用rbChain()函数获取扩展记录对应的数据链表;
- 按照一定的方式输出数据链表中的数据。
这样就完成了查看实体的扩展记录中的数据。
3.3 删除扩展记录
删除实体的扩展记录的步骤为:
- 使用extensionDictionary()函数获取实体的扩展字典;
- 使用remove()函数删除指定名称的扩展数据。
这样就完成了删除实体的扩展记录。
4 步骤
创建扩展记录Xrecord源代码:
//为实体添加Xrecord
static void MyGroupcreateXrecord()
{
//提示用户选择实体
AcDbObject* pObj = NULL;
if ((pObj = selectObject(AcDb::kForWrite)) == NULL)
{
return;
}
//提示用户输入要添加的数据
TCHAR xrecName[200], resString[200];
xrecName[0] = resString[0] = _T