首页 ObjectARX-扩展数据

ObjectARX-扩展数据

小白鼠 2019-04-04 12:46:25 0 3119

20180924205250107.gif

基本思路:

20180924205236765.jpg

(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
20180924213006197.png

③根据提示选择实体,然后按回车键

20180924213118494.png

现刚刚选择的三个实体,Xdata不可选说明没有扩展数据

20180924213210419.png

⑤实体 圆有扩展数据

20180924213333830.png

⑥点击Xdata,可看到其扩展数据:

20180924213443359.png

发表评论