关于扩展记录和扩展数据的读写

ObjectARX的扩展数据和扩展记录的定义及应用不再赘述,下面着重介绍如何将结果缓冲区作为参数传递给自定义读写函数。见代码:

1. 先创建一个测试命令,用于测试将扩展记录和扩展数据附加到一个实体。此处省略了如何将实体推入数据库的过程,即代码中的 AppendEntityToBlock()函数。

// 本例创建一个圆实体,并附加扩展数据和扩展记录
void Test()
{
	AcDbCircle* pCir = new AcDbCircle(AcGePoint3d(10, 10, 0), AcGeVector3d::kZAxis, 5.0);
	AcDbObjectId objId = AppendEntityToBlock(pCir);
	
    // 设置扩展记录
	struct resbuf* pRb1 = acutBuildList(AcDb::kDxfText, _RXST("演示1"), RTNONE);
	if (SetXRecord(objId, pRb1)) acutPrintf(_T("\n--- 添加扩展记录 成功 ---"));
	
	// 读取扩展记录
	struct resbuf* pRb2 = NULL;
	if (GetXRecord(objId, &pRb2))
	{
		if (pRb2)
		{
			acutPrintf(_T("\n--- 读取扩展记录:%s ---"), pRb2->resval.rstring);
			acutRelRb(pRb2);
		}
	}

	// 设置扩展数据
	// resbuf 的 restype 字段中只接受有效的 xdata 组代码(1000--1071), 
	// 这就以为着类型码的前缀只能是 AcDb::kDxfXd,AcDb::kDxfRegAppName 除外,否则添加不能成功
	struct resbuf* pRb3 = acutBuildList(AcDb::kDxfRegAppName, _RXST("WjcStudio_ObjectARX"), AcDb::kDxfXdAsciiString, _RXST("演示2"), RTNONE);
	if (SetXData(objId, pRb3))
		acutPrintf(_T("\n--- 添加扩展数据 成功 ---"));
	
	// 读取扩展数据
	struct resbuf* pRb4 = NULL;
	if (GetXData(objId, &pRb4))
	{
		if (pRb4)
		{
			acutPrintf(_T("\n--- 读取扩展数据:%s ---"), pRb4->rbnext->resval.rstring);
			acutRelRb(pRb4);
		}
	}
}

2. 设置扩展记录

//-----------------------------------------------------------------------------
// 为 AcDbObject 类对象添加扩展记录
// destObjId:AcDbObject 类的 ID -----------------------<input>
// *pSrcRb:结果缓冲区链表指针, 包含全部扩展记录的数据 ----<input>
// appName:应用程序名称,默认为 “WjcStudio_ObjectARX” ---<input>
// 返回:true-成功,false-失败
static bool SetXRecord(const AcDbObjectId& destObjId, struct resbuf* pSrcRb, 
	AcString appName = _RXST("WjcStudio_ObjectARX"))
{
	Acad::ErrorStatus es;
	AcDbObject* pObject = NULL;
	es = acdbOpenObject(pObject, destObjId, AcDb::kForWrite);
	if (es != Acad::eOk)
	{
		if (pSrcRb) acutRelRb(pSrcRb);//释放结果缓冲区
		return false;
	}

	es = pObject->createExtensionDictionary();//新建对象扩展字典
	if (es != Acad::eOk && es != Acad::eAlreadyInDb)
	{
		pObject->close();
		if (pSrcRb) acutRelRb(pSrcRb);
		return false;
	}

	AcDbObjectId dictId = NULL;	
	AcDbDictionary* pDict = NULL;
	dictId = pObject->extensionDictionary();
	pObject->close();
	if (dictId.isNull())
	{
		if (pSrcRb) acutRelRb(pSrcRb);
		return false;
	}

	//创建扩展记录实体
	AcDbXrecord* pXRecord = new AcDbXrecord();
	//向扩展字典中添加一条记录
	AcDbObjectId xRecordId = NULL;
	if (Acad::eOk == acdbOpenObject(pDict, dictId, AcDb::kForWrite))
	{
		es = pDict->setAt(appName, pXRecord, xRecordId);
		pDict->close();
	}
	if (Acad::eOk != es)
	{
		delete pXRecord;
		if (pSrcRb) acutRelRb(pSrcRb);
		return false;
	}	//设置扩展记录的内容

	es = pXRecord->setFromRbChain(*pSrcRb);
	pXRecord->close();
	if (pSrcRb) acutRelRb(pSrcRb);//释放结果缓冲区
	if (es != Acad::eOk) return false;

	return true;
}

3. 读取扩展记录

//-----------------------------------------------------------------------------
// 读取AcDbObject类对象的扩展记录
// destObjId:AcDbObject 类的 ID ----------------------------<input>
// **pSrcRb:结果缓冲区链表指针的指针, 包含全部扩展记录的数据 ---<output>
// appName:	应用程序名称,默认为 “WjcStudio_ObjectARX” --------<input>
// 返回:true-成功,false-失败
static bool GetXRecord(const AcDbObjectId& destObjId, struct resbuf** pRtnRb, 
	AcString appName = _RXST("WjcStudio_ObjectARX"))
{
	Acad::ErrorStatus es;
	AcDbObject* pObject = NULL;
	AcDbXrecord* pXRecord = NULL;
	AcDbDictionary* pDict = NULL;
	if (*pRtnRb) acutRelRb(*pRtnRb);
	*pRtnRb = NULL;

	// 打开对象
	es = acdbOpenObject(pObject, destObjId, AcDb::kForRead);
	if (es != Acad::eOk) return false;

	// 获取对象的扩展字典
	AcDbObjectId dictId = pObject->extensionDictionary();
	pObject->close();
	if (dictId.isNull()) return false;

	// 打开字典	
	es = acdbOpenObject(pDict, dictId, AcDb::kForRead);
	if (Acad::eOk != es) return false;

	// 获取指定应用程序的扩展记录
	es = pDict->getAt(appName, pXRecord, AcDb::kForRead);
	pDict->close();
	if (Acad::eOk != es) return false;

	// 扩展记录数据读入结果缓冲区
	es = pXRecord->rbChain(pRtnRb);
	pXRecord->close();
	if (Acad::eOk != es) return false;

	return true;
}

4. 设置扩展数据


//-----------------------------------------------------------------------------
// 为AcDbObject类对象添加扩展数据
// destObjId:AcDbObject 类的 ID -----------------------<input>
// *pRtnRb:	结果缓冲区链表指针, 包含全部扩展数据的数据 ----<input>
// appName:	应用程序名称,默认为 “WjcStudio_ObjectARX” ---<input>
// 返回:true-成功,false-失败
static bool SetXData(const AcDbObjectId& objectId, struct resbuf* pRtnRb,
	AcString appName = _RXST("WjcStudio_ObjectARX"))
{
	AcDbObject* pObject = NULL;
	if (Acad::eOk != acdbOpenObject(pObject, objectId, AcDb::kForWrite)) return false;

	int rtnRegApp = acdbRegApp(appName);
	if (rtnRegApp == RTNORM || rtnRegApp == RTERROR)
		pObject->setXData(pRtnRb);//新建或覆盖扩展数据
	pObject->close();
	if (pRtnRb) acutRelRb(pRtnRb); // 删除链表

	return true;
}

5. 读取扩展数据


//-----------------------------------------------------------------------------
// 读取AcDbObject类对象的扩展数据
// destObjId:AcDbObject 类的 ID ----------------------------<input>
// **pRtnRb:结果缓冲区链表指针的指针, 包含全部扩展数据的数据 ---<output>
// appName:应用程序名称,默认为 “WjcStudio_ObjectARX” --------<input>
// 返回:true-成功,false-失败
static bool GetXData(const AcDbObjectId& destObjId, struct resbuf** pRtnRb,
	AcString appName = _T("WjcStudio_ObjectARX"))
{
	if (*pRtnRb) acutRelRb(*pRtnRb);
	*pRtnRb = NULL;

	AcDbEntity* pObject = NULL;
	if (Acad::eOk != acdbOpenObject(pObject, destObjId, AcDb::kForRead)) return false;

	*pRtnRb = pObject->xData(appName);
	pObject->close();

	if ((*pRtnRb)) return true;
	return false;
}

6. 注意:①结果缓冲区(resbuf)作为Get函数的参数,应定义为指针的指针,否则不能返回结果;②结果缓冲区(resbuf)在使用前一定要判断是否为NULL,否则对其读取、删除会造成CAD崩溃;③指针(或指针的指针)型的结果缓冲区(resbuf)在使用完成后要记得释放(acutRelRb);④设置扩展数据时结果缓冲区(resbuf)的 restype 字段中只接受有效的 xdata 组代码(1000--1071),即前缀只能是 AcDb::kDxfXd,AcDb::kDxfRegAppName 除外,否则添加不能成功,扩展记录无此限制;⑤设置扩展数据时结果缓冲区(resbuf)的 第一个restype 字段必须是组码1001,即AcDb::kDxfRegAppName,多个扩展数据也是以AcDb::kDxfRegAppName作为分隔符号,扩展记录无此限制;⑥ 读写扩展数据时“注册的应用程序名称”必须和AcDb::kDxfRegAppName字段的 resval(值)相匹配。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值