【CAD二次開發】-ObjectARX-擴充套件資料 (Xdata)
阿新 • • 發佈:2018-12-11
基本思路:
(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();
}
}
完整的專案程式碼:
效果:
①先建立兩條直線,執行AddXData命令,選擇其中一條直線,為其新增擴充套件資料;
②執行ViewXData命令,檢視擴充套件資料
③執行DeleteXData命令,刪除擴充套件命令。
Reference:
張帆《AutoCAD ObjectARX(VC)開發基礎與例項教程》