乐子王

为计算机技术狂人带去乐趣

Dec
29

ObjectARX编程:AcDbXrecord扩展记录类的使用实例

类别: 玩转电脑

作者:陈锐 (本站原创,未经许可不得转载)

本文介绍了如何使用AcDbXrecord类来存储数据,示例演示了将自定义的数据结构的存储与读取,以及单独的字符串的存储与读取。

示例中使用的主要技术包括:

  1. 在AutoCAD中使用ObjectARX创建实体;
  2. 扩展记录中,自定义的数据结构的存储与读取;
  3. 扩展记录中,字符串的存储与读取;
  4. 使用sendStringToExecute函数执行命令;
  5. AcDbObjectPointer智能指针;
  6. 非模态对话框;
  7. 对话框设置菜单;
  8. 非模态对话框自动获取焦点;
  9. MFC打开文件对话框;
  10. CAcUiDialog

该ARX加载以后对话框即自动运行并显示,如下图:

image

当鼠标在对话框区域内时,对话框自动获取焦点;当鼠标移动到对话框区域以外时,AutoCAD自动获取焦点。

操作说明:

  1. 执行“绘制并写入扩展数据”,在图面上绘制直线,绘制完毕程序自动将自定义的数据结构MyStruct写入实体;
  2. 显示打开文件对话框,选择任意文件。选择完毕程序自动将文件路径存入实体的扩展记录。
  3. 执行“读取并显示扩展数据”,选择刚才绘制的直线,程序自动读取并显示刚才写入的所有数据。

以下是几个主要函数的代码:

将自定义数据结构转化为链表
MyStruct myData;
struct resbuf* pData = acutNewRb(AcDb::kDxfBinaryChunk);
pData->resval.rbinary.buf = static_cast<char*>(malloc(sizeof(myData)));
memcpy(pData->resval.rbinary.buf,(const void *)&myData,sizeof(myData));
pData->resval.rbinary.clen = sizeof(myData);
写入扩展记录
bool PubFun::WriteXRecord(struct resbuf* pRbValue,const AcDbObjectId &id,LPCTSTR pszxRecordName)
{
AcDbObjectPointer<AcDbObject> pObj(id,AcDb::kForWrite);
if(pObj.openStatus() != Acad::eOk)
{
return false;
}if(pszxRecordName == NULL || pRbValue == NULL)
{
acutPrintf(_T(”\n参数为空!”));
return false;
}
//得到实体的字典ID
AcDbObjectId extDictId = pObj->extensionDictionary();
if (extDictId == AcDbObjectId::kNull)
{
Acad::ErrorStatus es = pObj->createExtensionDictionary();
if (es != Acad::eOk)
{
acutPrintf(_T(”\n创建扩展字典错误:%d!”),es);
return false;
}
if ((extDictId = pObj->extensionDictionary()) == AcDbObjectId::kNull)
{
acutPrintf(_T(”\n错误: 不能创建扩展字典!”));
return false;
}
}
//创建新的扩展记录
AcDbDictionaryPointer pDict(extDictId,AcDb::kForRead);
if(pDict.openStatus() != Acad::eOk)
{
acutPrintf(_T(”\n读方式打开字典失败!”));
return false;
}
AcDbObjectId xRecId;
if(pDict->getAt(pszxRecordName,xRecId) != Acad::eOk)
{
AcDbXrecord* pXrec = new AcDbXrecord;
pDict->upgradeOpen();
if(pDict->setAt(pszxRecordName,pXrec,xRecId) != Acad::eOk)
{
acutPrintf(_T(”\n创建新的扩展记录数据失败!”));
return false;
}
pXrec->close();
}
//写数据
AcDbObjectPointer<AcDbXrecord> pXrcord(xRecId,AcDb::kForWrite);
if(pXrcord.openStatus() != Acad::eOk)
{
acutPrintf(_T(”\n写方式打开扩展记录失败”));
return false;
}
else
{
if(pXrcord->setFromRbChain(*pRbValue) != Acad::eOk)
{
acutPrintf(_T(”\nsetFromRbChain() 失败!”));
return false;
}
}
return true;
}
读取扩展记录
struct resbuf* PubFun::ReadXRecord(const AcDbObjectId &id,LPCTSTR pszxRecordName)
{
AcDbObjectPointer<AcDbObject> pObj(id,AcDb::kForRead);
if(pObj.openStatus() != Acad::eOk)
{
return NULL;
}//打开字典
AcDbObjectId extDictId;
extDictId = pObj->extensionDictionary();
if (extDictId == AcDbObjectId::kNull)
{
acutPrintf(_T(”\n没有扩展字典!”));
return NULL;
}
AcDbDictionaryPointer pDict(extDictId,AcDb::kForRead);
if(pDict.openStatus() != Acad::eOk)
{
acutPrintf(_T(”\n读方式打开字典失败!”));
return NULL;
}
//打开扩展记录
AcDbObjectId xRecId;
if(pDict->getAt(pszxRecordName,xRecId) != Acad::eOk)
{
acutPrintf(_T(”\n%s:没有扩展记录!”),pszxRecordName);
return NULL;
}
struct resbuf *pData = NULL;
AcDbObjectPointer<AcDbXrecord> pXrcord(xRecId,AcDb::kForRead);
if(pXrcord.openStatus() != Acad::eOk)
{
acutPrintf(_T(”\n读方式打开扩展记录失败”));
return NULL;
}
else
{
pXrcord->rbChain(&pData);
}
return pData;
}

示例ARX下载:XRecordTest.arx
源码下载:XRecordTest.rar

转载必须注明文章来源于乐子王,否则后果自负!

标签: , , , , , , , ,

没有相关文章

随机文章:

喷喷口水

尊姓大名

电子邮箱 (不会被公开)

网址

XHTML: 你可以使用这些标记: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

关于乐子王

    

    关于这个网站

    这是一个适合计算机技术爱好者的网站,这里有很多新奇、有趣甚至是奇奇怪怪的软件、网站,有专为技术狂人准备的漫画,有漂亮的图片,有令人惊叹的视频,还有狂人们折磨、折腾电脑的经验技巧。 有人说,这个网站的东西我怎么看不懂啊?那是因为,这里的乐趣,只有技术狂人才会明白……

    关于我

    我热爱王小波,我本能地渴望自由,我崇尚智慧,我希望有一天,可以不用工作,不用见客户,每天睡到自然醒。 我的邮箱:greenmangy@gmail.com

    豫ICP备08000845号