基本思路:
(1)创建一个新项目,命名为Xdata.注册一个命令AddXData.
实现代码为:
static void AAAMyGroupAddXData() {
// 提示用户选择所要添加扩展数据的图形对象
AcDbEntity *pEnt = NULL;
AcGePoint3d pickPoint;
if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要添加的扩展数据的实体:"),
AcDbEntity::desc(),pEnt,pickPoint))
{
CString appName = TEXT("XDataApp");
//注册应用程序名称
acdbRegApp(appName);
//创建结果缓冲区链表
struct resbuf* rb = acutBuildList(AcDb::kDxfRegAppName, appName,
//应用程序名称
AcDb::kDxfXdAsciiString, TEXT("字符串测试数据"),//字符创
AcDb::kDxfXdInteger32, 2,//整数
AcDb::kDxfXdReal, 3.14,//实数
AcDb::kDxfXdWorldXCoord, asDblArray(pickPoint),//点坐标值
RTNONE);
//为选择的实体添加扩展数据
pEnt->setXData(rb);
acutRelRb(rb);
acutPrintf(TEXT("\n成功为实体添加了扩展数据."));
pEnt->close();
}
}
// Modal Command with pickfirst selection
// ACED_ARXCOMMAND_ENTRY_AUTO(CXdataApp, AAAMyGroup, MyPickFirst, MyPickFirstLocal, ACRX_CMD_MODAL | ACRX_CMD_USEPICKSET)
static void AAAMyGroupMyPickFirst () {
ads_name result ;
int iRet =acedSSGet (ACRX_T("_I"), NULL, NULL, NULL, result) ;
if ( iRet == RTNORM )
{
// There are selected entities
// Put your command using pickfirst set code here
}
else
{
// There are no selected entities
// Put your command code here
}
}
创建一个类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;
}
}
(2)注册一个ViewXData命令,用于查看指定的实体的扩展数据。
实现函数为:
static void AAAMyGroupViewXData() {
//提示用户选择所要查看扩展数据的图形对象
AcDbEntity *pEnt = NULL;
AcGePoint3d pickPoint;
if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要添加扩展数据的实体:"), AcDbEntity::desc(), pEnt, pickPoint))
{
CString appName = TEXT("XDataApp");
//获取实体的扩展数据
struct resbuf *pRb = pEnt->xData(appName);
if (pRb != NULL)
{
//在命令行显示所有的扩展数据
struct resbuf *pTemp = pRb; //使用临时的结果缓冲区指针进行
//遍历,pRb不修改便于释放
//首先要跳过数据名称这一项
pTemp = pTemp->rbnext;
acutPrintf(TEXT("\n字符串类型的扩展数据是:%s"), pTemp->resval.rstring);
pTemp = pTemp->rbnext;
acutPrintf(_T("\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);
}
else
{
acutPrintf(TEXT("\n所选择的实体不包含任何的扩展数据!"));
}
pEnt->close();
}
}
(3)注册新命令DeleteXData,用于从实体中删除特定的扩展数据.
实现代码:
static void AAAMyGroupDeleteXData() {
//提示用户选择所要删除扩展数据的图形对象
AcDbEntity *pEnt = NULL;
AcGePoint3d pickPoint;
if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要删除扩展数据的实体:"),
AcDbEntity::desc(),pEnt,pickPoint))
{
CString appName = TEXT("XDataApp");
//注册应用程序名称
acdbRegApp(appName);
//创建结果缓冲区链表
struct resbuf *rb = acutBuildList(AcDb::kDxfRegAppName, appName, RTNONE);
//应用程序名称
//设置内容为空的结果缓冲区链表就是删除扩展数据
pEnt->setXData(rb);
acutRelRb(rb);
acutPrintf(TEXT("\n成功为实体删除了扩展数据."));
pEnt->close();
}
}
完整的项目代码:
https://pan.baidu.com/s/1MSW-sefDViI244swYH8XFA
效果:
①先创建两条直线,执行AddXData命令,选择其中一条直线,为其添加扩展数据;
②执行ViewXData命令,查看扩展数据
③执行DeleteXData命令,删除扩展命令。
还没有结束!
还有另一种查看扩展数据的方法:
①在CAD中加载ArxDbg.arx
如果你没有这个使用程序,我这里提供给您下载:
https://pan.baidu.com/s/1q5fJ94q2RcPNXgvmvbQYDA
包括从AutoCAD 2000到AutoCAD 2019的所有AutoCAD版本
②右键,选择EntityInfo
③根据提示选择实体,然后按回车键
④出现刚刚选择的三个实体,Xdata不可选说明没有扩展数据
⑤实体 圆有扩展数据
⑥点击Xdata,可看到其扩展数据:
Reference:
张帆《AutoCAD ObjectARX(VC)开发基础与实例教程》