发布时间:2025-12-09 15:55:19 浏览次数:4
ObjectARX开发过程中,有时会使用自定义数据,主要包括:
定义:
int acdbRegApp(const ACHAR * appname);作用:在当前图形中注册一个应用程序名称,用于分组,存储,检索和修改实体的扩展数据。appname必须遵守符号表名称(例如图层名称)的规则,且不能和已经存在的RegApp重复。每个新名称将产生一个新的acdbRegApp记录。
返回值:
定义:
virtual Acad::ErrorStatus setXData(const resbuf* xdata);作用:设置一个对象的扩展数据。
返回值:
定义:
virtual resbuf* xData(const ACHAR* regappName = nullptr) const;作用:获取一个对象中名为“regappName”的扩展数据。如果regappName == NULL,则返回所有xdata,否则仅返回指定名称为regappName的xdata。如果需要多个regappName的xdata,则必须对该成员函数进行多次调用,每个regappName调用一次。
返回值:
添加Xdata代码如下:
//添加Xdatastatic void MyGroupaddXdata() {//提示用户选择对象AcDbObject* pObj = selectObject(AcDb::kForRead);if (!pObj) {acutPrintf(_T("Error selecting object\n"));return;}//获取Xdata名称TCHAR appName[132], resString[200];appName[0] = resString[0] = _T('\0');acedGetString(NULL, _T("Enter application name: "), appName);acedGetString(NULL, _T("Enter string to be added: "), resString);struct resbuf *pRb, *pTemp;pRb = pObj->xData(appName);if (pRb != NULL) {//如果Xdata已经存在,不执行任何操作for (pTemp = pRb; pTemp->rbnext != NULL;pTemp = pTemp->rbnext){ ; }} else {//如果Xdata不存在,向当前对象注册名为appName的XdataacdbRegApp(appName);pRb = acutNewRb(AcDb::kDxfRegAppName);pTemp = pRb;pTemp->resval.rstring= (TCHAR*) malloc((_tcslen(appName) + 1) * sizeof(TCHAR));_tcscpy(pTemp->resval.rstring, appName);}//向新注册的Xdata添加自定义扩展数据pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString);pTemp = pTemp->rbnext;pTemp->resval.rstring= (TCHAR*) malloc((_tcslen(resString) + 1) * sizeof(TCHAR));_tcscpy(pTemp->resval.rstring, resString);//把对象从AcDb::kForRead 状态变成AcDb::kForWrite状态pObj->upgradeOpen();pObj->setXData(pRb);pObj->close();acutRelRb(pRb);}查看Xdata代码如下:
//显示Xdatastatic void MyGroupprintXdata(){//提示用户选择对象AcDbObject *pObj;if ((pObj = selectObject(AcDb::kForRead)) == NULL) {return;}//获取Xdata名称TCHAR appname[133];if (acedGetString(NULL,_T("\nEnter the desired Xdata application name: "),appname) != RTNORM){return;}// 根据Xdata名称appname,调用printList()函数输出Xdata信息struct resbuf *pRb;pRb = pObj->xData(appname);if (pRb != NULL) {printList(pRb);acutRelRb(pRb);} else {acutPrintf(_T("\nNo xdata for this appname"));}pObj->close();}删除Xdata代码如下:
//删除Xdatastatic void MyGroupdeleteXdata(){AcDbObject* pObj = selectObject(AcDb::kForRead);if (!pObj) {acutPrintf(_T("Error selecting object\n"));return;}//获取Xdata名称TCHAR appName[132];appName[0] = _T('\0');acedGetString(NULL, _T("Enter application name: "), appName);//在pObj的Xdata中查找appNamestruct resbuf *pTemp = nullptr; pTemp = pObj -> xData(appName);if (pTemp != nullptr){// 删除名为appName的XdataacdbRegApp(appName);struct resbuf* pRb = acutBuildList(AcDb::kDxfRegAppName, appName, RTNONE);pObj->upgradeOpen();pObj->setXData(pRb);acutRelRb(pRb);acutPrintf(TEXT("\nXdata deleted successfully."));}else{//未找到需要删除的XdataacutPrintf(TEXT("\nNo Xdata found."));}acutRelRb(pTemp);pObj->close();}还需要添加两个函数,printList()用于在命令窗口中打印Xdata信息;selectObject()用于提示用户选择实体。代码如下:
//在AutoCAD命令窗口中打印Xdata信息static void printList(struct resbuf* pRb){int rt, i;TCHAR buf[133];for (i = 0;pRb != NULL;i++, pRb = pRb->rbnext) {if (pRb->restype < 1010) {rt = RTSTR;} else if (pRb->restype < 1040) {rt = RT3DPOINT;} else if (pRb->restype < 1060) {rt = RTREAL;} else if (pRb->restype < 1071) {rt = RTSHORT;} else if (pRb->restype == 1071) {rt = RTLONG;} else {rt = pRb->restype; }switch (rt) {case RTSHORT:if (pRb->restype == RTSHORT) {acutPrintf(_T("RTSHORT : %d\n"), pRb->resval.rint);} else {acutPrintf(_T("(%d . %d)\n"), pRb->restype,pRb->resval.rint);};break;case RTREAL:if (pRb->restype == RTREAL) {acutPrintf(_T("RTREAL : %0.3f\n"),pRb->resval.rreal);} else {acutPrintf(_T("(%d . %0.3f)\n"), pRb->restype,pRb->resval.rreal);};break;case RTSTR:if (pRb->restype == RTSTR) {acutPrintf(_T("RTSTR : %s\n"),pRb->resval.rstring);} else {acutPrintf(_T("(%d . \"%s\")\n"), pRb->restype,pRb->resval.rstring);};break;case RT3DPOINT:if (pRb->restype == RT3DPOINT) {acutPrintf(_T("RT3DPOINT : %0.3f, %0.3f, %0.3f\n"),pRb->resval.rpoint[X],pRb->resval.rpoint[Y],pRb->resval.rpoint[Z]);} else {acutPrintf(_T("(%d %0.3f %0.3f %0.3f)\n"),pRb->restype,pRb->resval.rpoint[X],pRb->resval.rpoint[Y],pRb->resval.rpoint[Z]);}break;case RTLONG:acutPrintf(_T("RTLONG : %dl\n"), pRb->resval.rlong);break;}if ((i == 23) && (pRb->rbnext != NULL)){i = 0;acedGetString(0,_T("Press <ENTER> to continue..."), buf);}}}//提示用户选择实体static AcDbObject*selectObject(AcDb::OpenMode openMode){int ss;ads_name en;ads_point pt;acedInitGet(RSG_OTHER, _T("Handle _Handle"));ss = acedEntSel(_T("\nSelect an Entity or enter")_T(" 'H' to enter its handle: "), en, pt);TCHAR handleStr[132];AcDbObjectId eId;switch (ss) {case RTNORM: break;case RTKWORD:if ((acedGetString(Adesk::kFalse,_T("Enter Valid Object Handle: "),handleStr) == RTNORM)&& (acdbHandEnt(handleStr, en) == RTNORM)){break;}default:acutPrintf(_T("Nothing Selected, Return Code==%d\n"),ss);return NULL;}Acad::ErrorStatus retStat;retStat = acdbGetObjectId(eId, en);if (retStat != Acad::eOk) {acutPrintf(_T("\nacdbGetObjectId failed"));acutPrintf(_T("\nen==(%lx,%lx), retStat==%d\n"),en[0], en[1], eId);return NULL;}AcDbObject* obj;if ((retStat = acdbOpenObject(obj, eId, openMode))!= Acad::eOk){acutPrintf(_T("acdbOpenEntity failed: ename:(%lx,%lx),")_T(" mode:%d retStat:%d"), en[0], en[1],openMode, retStat);return NULL;}return obj;}使用“addXdata”命令选择实体并添加扩展数据,“printXdata”命令在AutoCAD的命令窗口显示添加的扩展数据,“deleteXdata”命令删除扩展数据。如下图所示,使用Xdata向图中被选中直线追加了自定义数据。
源代码:xData
提取码:4bbm
参考文档
[1]:Autodesk ObjectARX for AutoCAD 2015: Developer Guide.