ObjectARX-扩展字典和有名对象字典(Xrecord)
思路:
(1)使用ObjectARX向导创建一个新工程Xrecord.
注册命令AddXRecord,提示用户选择一个实体,并将一些附加的数据保存到该实体的扩展字典中。
实现函数:
static void AAAMyGroupAddRecord() {
//提示用户选择所要添加扩展记录的图形对象
AcDbEntity *pEnt = NULL;
AcGePoint3d pickPoint;
if (CSelectUtil::PromptSelectEntity(TEXT("\n 选择所要添加扩展记录的实体"),
AcDbEntity::desc(),pEnt,pickPoint))
{
//向实体中添加扩展字典
pEnt->createExtensionDictionary(); //为实体建立扩展字典
AcDbObjectId dictObjId = pEnt->extensionDictionary(); //获得
//实体的扩展字典
pEnt->close();
//创建扩展记录实体
AcDbXrecord *pXrec = new AcDbXrecord;
//向扩展字典中添加一条记录
AcDbObjectId xRecObjId;
AcDbDictionary *pDict = NULL;
if (acdbOpenObject(pDict,dictObjId,AcDb::kForWrite) == Acad::eOk)
{
pDict->setAt(TEXT("XRecord"), pXrec, xRecObjId);
pDict->close();
}
//设置扩展记录的内容
struct resbuf* pRb = acutBuildList(AcDb::kDxfText, TEXT("测试字符串数据"),
AcDb::kDxfInt32, 12,
AcDb::kDxfReal, 3.14,
AcDb::kDxfXCoord, asDblArray(pickPoint),
RTNONE);
pXrec->setFromRbChain(*pRb); //扩展数据内容填充扩展记录对象
pXrec->close();
acutRelRb(pRb);
}
}
代码表示:如果"XRecord"还没有在字典中存在,那么这个函数就会在字典中添加新的条目,并将它添加到字典中。如果带有关键"XRecord"的条目已经存在,那么现有的条目将被删除,字典从它的反应堆列表中删除,并且它被新的值对象替换为它所处的字典。该对象的名称由"XRecord"指定。对象的objectId条目在 xRecObjId中返回。
"XRecord"
输入字符串表示对象的搜索键名
pXrec
输入指向新对象的指针以添加到字典中
xRecObjId
返回新添加对象的对象ID
其中,PromptSelectEntity函数的实现:
首先,创建一个类CSelectUtil,在此类中实现PromptSelectEntity。
函数的声明:
// 提示用户选择某个类型的实体
// 注意:调用者必须关闭实体
static bool PromptSelectEntity(const TCHAR* prompt, AcRxClass* classDesc, AcDbEntity *&pEnt, AcGePoint3d &pickPoint,
bool bOpenForWrite = true);
static bool PromptSelectEntity(const TCHAR* prompt, const std::vector<AcRxClass*> &classDescs, AcDbEntity *&pEnt,
AcGePoint3d &pickPoint, bool bOpenForWrite = true);
函数的实现:
bool CSelectUtil::PromptSelectEntity( const TCHAR* prompt, AcRxClass* classDesc, AcDbEntity *&pEnt,
AcGePoint3d &pickPoint, bool bOpenForWrite /*= true*/ )
{
std::vector<AcRxClass*> descs;
descs.push_back(classDesc);
return PromptSelectEntity(prompt, descs, pEnt, pickPoint, bOpenForWrite);
}
bool CSelectUtil::PromptSelectEntity( const TCHAR* prompt, const std::vector<AcRxClass*> &classDescs, AcDbEntity *&pEnt,
AcGePoint3d &pickPoint, bool bOpenForWrite /*= true*/ )
{
ads_name ename;
RETRY:
if (acedEntSel(prompt, ename, asDblArray(pickPoint)) != RTNORM)
{
pEnt = NULL;
return false;
}
AcDbObjectId entId;
acdbGetObjectId(entId, ename);
// 判断选择的实体是否是指定类型的实体
Acad::ErrorStatus es;
if (bOpenForWrite)
{
es = acdbOpenObject(pEnt, entId, AcDb::kForWrite);
}
else
{
es = acdbOpenObject(pEnt, entId, AcDb::kForRead);
}
assert (es == Acad::eOk);
bool bRet = false;
for (int i = 0; i < (int)classDescs.size(); i++)
{
if (pEnt->isKindOf(classDescs[i]))
{
bRet = true;
break;
}
}
if (bRet)
{
return true;
}
else
{
pEnt->close();
acutPrintf(TEXT("\n选择的实体类型不合要求, 请再次选择..."));
goto RETRY;
}
}
添加头文件:
#include <vector>
(2)注册新命令ViewXRecord,查看扩展字典中“XRecord”元素所保存的数据。
实现函数
static void AAAMyGroupViewXRecord() { //提示用户选择所要查看扩展记录的图形对象 AcDbEntity *pEnt = NULL; AcGePoint3d pickPoint; if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要查看扩展记录的实体:"), AcDbEntity::desc(),pEnt,pickPoint)) { //获得实体的扩展字典 AcDbObjectId dictObjId = pEnt->extensionDictionary(); pEnt->close(); if (dictObjId.isNull()) { acutPrintf(TEXT("\n 所选择的实体不包含扩展字典!")); return; } //打开扩展字典,获得与关键字"XRecord"关联的扩展记录 AcDbDictionary *pDict = NULL; AcDbXrecord *pXrec = NULL; struct resbuf *pRb = NULL; if (acdbOpenObject(pDict,dictObjId,AcDb::kForRead) == Acad::eOk) { pDict->getAt(TEXT("xRecord"), (AcDbObject*&)pXrec, AcDb::kForRead); //获得扩展记录的数据链表并关闭扩展数据对象 pXrec->rbChain(&pRb); pXrec->close(); pDict->close(); } if (pRb != NULL) { //在命令行显示扩展记录内容 struct resbuf *pTemp = pRb; acutPrintf(TEXT("\n字符串类型的扩展数据是:%s"), pTemp->resval.rstring); pTemp = pTemp->rbnext; acutPrintf(TEXT("\n整数类型的扩展数据是:%d"), pTemp->resval.rint); pTemp = pTemp->rbnext; acutPrintf(TEXT("\n整数类型的扩展数据是:%.2f"), pTemp->resval.rreal); pTemp = pTemp->rbnext; acutPrintf(TEXT("\n点坐标类型的扩展数据是:(%.2f,%.2f,%.2f)"), pTemp->resval.rpoint[X], pTemp->resval.rpoint[Y], pTemp->resval.rpoint[Z]); acutRelRb(pRb); } } }
(3)注册命令AddNameDict,向当前的图形数据库中添加一个字典,并在其中保存自定义数据。
实现函数为:
static void AAAMyGroupAddNameDict() { // 获得有名对象字典,向其中添加指定的字典项 AcDbDictionary *pNameObjDict = NULL; acdbHostApplicationServices()->workingDatabase() ->getNamedObjectsDictionary(pNameObjDict, AcDb::kForWrite); //检查所要添加的字典项是否已经存在 AcDbObjectId dictObjId; AcDbDictionary *pDict = NULL; if (pNameObjDict->getAt(TEXT("MyDict"), (AcDbObject*&)pDict, AcDb::kForWrite) == Acad::eKeyNotFound) { pDict = new AcDbDictionary; pNameObjDict->setAt(TEXT("MyDict"), pDict, dictObjId); pDict->close(); } pNameObjDict->close(); //向新建的字典中添加一个图层对象 if (acdbOpenObject(pDict, dictObjId, AcDb::kForWrite) == Acad::eOk) { AcDbLayerTableRecord *pLayer = new AcDbLayerTableRecord(); AcCmColor color; color.setColorIndex(20); pLayer->setColor(color); pLayer->setIsOff(true); pLayer->setIsFrozen(true); AcDbObjectId layerId; Acad::ErrorStatus es = pDict->setAt(TEXT("LayerKey"), pLayer, layerId); pLayer->close(); pDict->close(); } }
(4)注册一个新命令ViewNameDict,检查当前图形中是否包含指定的用户字典,并在命令窗口中显示字典中保存的自定义数据。
实现函数:
static void AAAMyGroupViewNameDict() { // 获得对象有名字典中指定的字典项 AcDbDictionary *pNameObjDict = NULL; Acad::ErrorStatus es; acdbHostApplicationServices()->workingDatabase() ->getNamedObjectsDictionary(pNameObjDict, AcDb::kForRead); AcDbDictionary *pDict = NULL; es = pNameObjDict->getAt(TEXT("MyDict"), (AcDbObject*&)pDict, AcDb::kForRead); pNameObjDict->close(); //如果不存在指定的字典项,则退出程序 if (es == Acad::eKeyNotFound) { acutPrintf(TEXT("\n 不存在字典项MyDict.")); return; } //获得指定的对象字典中的对象 AcDbLayerTableRecord *pLayer = NULL; if (pDict->getAt(TEXT("LayerKey"), (AcDbObject*&)pLayer, AcDb::kForRead) == Acad::eOk) { //获得实体信息 int colorIndex = pLayer->color().colorIndex(); bool bOff = pLayer->isOff(); bool bFrozen = pLayer->isFrozen(); pLayer->close(); //在命令行打印实体信息 acutPrintf(TEXT("\n 字典中的图层颜色: %d"), colorIndex); acutPrintf(TEXT("\n 字典中的图层是否是关闭状态: %s"), bOff ? TEXT("是") : TEXT("否")); acutPrintf(TEXT("\n 字典中的图层是否是冻结状态: %s"), bFrozen ? TEXT("是") : TEXT("否")); } pDict->close(); }
效果:
①在AutoCAD中加载应用程序,并执行AddXRecord,在图形窗口中选择一个实体,即可为图形添加扩展字典
②执行ViewXReocrd命令,查看扩展字典:
③利用ArxDbg工具查看:
⑥执行命令AddNameDict向图形的有名对象字典中添加用户字典。
⑦执命令ViewNameDict:
用ArxDbg也能观察有名对象字典的内容:

转载请注明出处: 芝麻开花
本文的链接地址: http://www.vmould.cn/?post=166
发表评论 取消回复