1 .在开发自定义数据ObjectARX期间,可能主要使用以下自定义数据:
使用自定义对象——,可以向AutoCAD添加与AutoCAD本身的实体功能相同的第三方实体类型,也可以自由封装数据。 此外,ObjectARX程序还提供了对自定义实体显示的灵活控制。 扩展数据——可以添加到图形本身或图形中的实体中。
扩展数据分为xdata(extensiondata )和xrecord两种。 2 .可以灵活地添加一定数量的扩展(Xdata ),以便开发人员可以使用2.Xdata AutoCAD数据库中的任何对象。 扩展数据的含义由开发人员自行解释,AutoCAD只维护这些数据。 那个意思没有关系。 扩展数据是链表组,每个组是链表系列,以名称开头。 这个名字是APP名称。 使用acdbRegApp ()注册APP应用程序名称,最多附加31个字符的数据表不能超过16K。 XF组码只能采用1000~1071之间的组码值。 2.1 Xdata相关函数—acdbRegApp 定义
intacdbregapp (consta char * appname );作用:在当前图形中注册用于对实体的扩展数据进行分组、存储、检索和修改的APP应用程序名称。 appname必须遵循符号表名称规则(如层名称),且不能与已存在的RegApp重复。 将为每个新名称生成新的acdbRegApp记录。返回值
成功注册appname,返回RTNORM; appname已经存在,返回RTERROR; 注册appname失败。 返回指示失败原因的ERRNO系统变量。 2.2 Xdata相关函数—setXData 定义
virtual acad :3360 errorstatussetxdata (const resbuf * xdata );作用:设置对象的扩展数据。
每个注册(regappname )链表必须用restype=1001分隔,并且resval.rstring必须是有效字符。 RegappName必须存在于AcDbRegAppTable中。 如果xdata中已经有此regappname组,则会覆盖新的链表。 要清除包含xdata的regappname的所有内容,只需创建一个以此regappname开头的空链表。返回值
如果xdata成功添加到对象中,则返回Acad : eOk。 如果对象的xdata区域没有足够的空间,则返回acad :3360 exdatasizeexceeded。 如果xdata中的所有regappName都不存在,则返回Acad : eRegappIdNotFound。 2.3 Xdata相关函数—XData 定义
虚拟resbuf * xdata (consta char * reg appname=null ptr ) const;作用:获取对象名为“regappName”的扩展数据。 如果regappName==NULL,则返回所有xdata。 否则,只返回具有指定名称的regappName的xdata。 如果需要多个regappName的xdata,则必须多次调用其成员函数,并为每个regappName调用一次。返回值
返回指向包含对象xdata副本的resbuf结构的链接列表。 2.4添加、查看和删除Xdata实例、Xdata添加、删除Xdata代码如下:
//xdatastaticvoidmygroupaddxdata (添加)//提示用户选择对象acdb object * pobj=select object (acdb : kforread ) pobj({acutprintf(_t ) ‘ errorselectingobject\n ‘ ) }; 返回; Xdata名称TCHAR appName[132],resString[200]; appName[0]=resString[0]=_T(‘\0 ‘ ); acedgetstring(null,_t ) ‘ enterapplicationname: ‘,appName ); acedgetstring(null,_t ) enterstringtobeadded: )、resString ); 结构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:3360KD
xfRegAppName);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;} 3.代码效果
使用“addXdata”命令选择实体并添加扩展数据,“printXdata”命令在AutoCAD的命令窗口显示添加的扩展数据,“deleteXdata”命令删除扩展数据。如下图所示,使用Xdata向图中被选中直线追加了自定义数据。
4.源代码
源代码:xData
提取码:4bbm
参考文档
[1]:Autodesk ObjectARX for AutoCAD 2015: Developer Guide.