#include "stdafx.h" #include "geassign.h" #include "acutmem.h" #include "TDbXDataMap.h" #include #include "dbxrecrd.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define MAP_BLOCK_BEGIN _T("TDBXDATAMAP_BLOCK_BEGIN_") #define MAP_BLOCK_END _T("TDBXDATAMAP_BLOCK_END_") #define DIF_VT_PT _T("$vector3d") // 设置向量是在键值pszkey后增加字符串"$vector3d",与点进行区分 #define _ttof _tstof TDbXDataMap::TDbXDataMap() { } TDbXDataMap::TDbXDataMap(const TDbXDataMap& datamap) { if (this != &datamap) { //map 互相复制 m_xData.erase(m_xData.begin(),m_xData.end()); m_xData.clear(); CopyFrom(&datamap); } } //bslmodyfied2010.11.3 // /* struct DelStringFunc { void operator () (std::pair& pairT) const { if (pairT.second.nVt == VT_BSTR || pairT.second.nVt == (VT_BYREF | VT_R8 + 4) ) { if (pairT.second.pszVal != NULL && pairT.second.npszLen > 0) { delete [] pairT.second.pszVal; pairT.second.pszVal = NULL; pairT.second.npszLen = 0; } } } }; */ TDbXDataMap::~TDbXDataMap() { //释放 xData 是自符串的元素 // std::for_each(m_xData.begin(),m_xData.end(),DelStringFunc()); std::map::iterator itor; for (itor = m_xData.begin();itor != m_xData.end();++itor) { if (itor->second.nVt == VT_BSTR || itor->second.nVt == (VT_BYREF | VT_R8 + 4) ) { if (itor->second.pszVal != NULL && itor->second.npszLen > 0) { delete [] itor->second.pszVal; itor->second.pszVal = NULL; itor->second.npszLen = 0; } } } } BOOL TDbXDataMap::SetAt( LPCTSTR pszKey,int nVal ) { if (pszKey != NULL) { TXData xdata; memset(&xdata,0,sizeof(xdata)); xdata.nVt = VT_I4; xdata.nVal = nVal; It it = m_xData.find(pszKey); if (it != m_xData.end()) { (*it).second = xdata; } else { std::pair pa(pszKey,xdata); m_xData.insert(pa); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,double dVal) { if (pszKey != NULL) { TXData xdata; memset(&xdata,0,sizeof(xdata)); xdata.nVt = VT_R8; xdata.dVal[0] = dVal; It it = m_xData.find(pszKey); if (it != m_xData.end()) { (*it).second = xdata; } else { std::pair pa(pszKey,xdata); m_xData.insert(pa); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,const AcGeDoubleArray& arVal) { if (pszKey != NULL) { CString sSubKey; for (int i = 0;i < arVal.length();++i) { sSubKey.Format(_T("%s%d"),pszKey,i); SetAt(sSubKey,arVal[i]); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,const AcGeVector3d& vt,BOOL bTransformBy) { /* 设置向量是在键值pszkey后增加字符串"$vector3d",与点进行区分 bTransformBy标识向量是否随cad实体所变化 */ if (pszKey != NULL) { CString sTmpKey = pszKey; sTmpKey += DIF_VT_PT; TXData xdata; memset(&xdata,0,sizeof(xdata)); xdata.nVt = (VT_BYREF | VT_R8 + 2); if(bTransformBy) { // 向量随cad实体变化而改变 xdata.nVt = (VT_BYREF | VT_R8 + 3); } xdata.dVal[0] = vt.x; xdata.dVal[1] = vt.y; xdata.dVal[2] = vt.z; It it = m_xData.find(sTmpKey); if (it != m_xData.end()) { (*it).second = xdata; } else { std::pair pa(sTmpKey,xdata); m_xData.insert(pa); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,const AcGePoint3d& ptGe,BOOL bTransformBy) { /* bTransformBy标识点是否随cad实体所变化 */ if (pszKey != NULL) { TXData xdata; memset(&xdata,0,sizeof(xdata)); xdata.nVt = VT_BYREF | VT_R8; if (bTransformBy) { // 点随cad实体变化而改变 xdata.nVt = (VT_BYREF|VT_R8 + 1); } xdata.dVal[0] = ptGe.x; xdata.dVal[1] = ptGe.y; xdata.dVal[2] = ptGe.z; It it = m_xData.find(pszKey); if (it != m_xData.end()) { (*it).second = xdata; } else { std::pair pa(pszKey,xdata); m_xData.insert(pa); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,const AcGePoint3dArray& arPt,BOOL bTransformBy) { if (pszKey != NULL) { CString sSubKey; for (int i = 0;i < arPt.length();++i) { sSubKey.Format(_T("%s%d"),pszKey,i); SetAt(sSubKey,arPt[i],bTransformBy); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,const AcGeMatrix3d& xform) { if (pszKey != NULL) { TXData xdata; memset(&xdata,0,sizeof(xdata)); xdata.nVt = (VT_BYREF | VT_R8 + 4); CString sText = _T(""),sTemp; for (int i = 0;i < 4;i++) { for (int j = 0;j < 4;j++) { sTemp.Format(_T("%g"),xform.entry[i][j]); sText += _T(",") + sTemp; } } sText.TrimLeft(_T(",")); xdata.npszLen = sText.GetLength() + 1; xdata.pszVal = new TCHAR[xdata.npszLen]; _tcscpy(xdata.pszVal,sText); It it = m_xData.find(pszKey); if (it != m_xData.end()) //找到 { if ( (*it).second.nVt == VT_BSTR || (*it).second.nVt == (VT_BYREF | VT_R8 + 4) ) { if ( (*it).second.npszLen > 0 && (*it).second.pszVal != NULL) { delete [] (*it).second.pszVal; } } (*it).second = xdata; } else //未找到 { std::pair pa(pszKey,xdata); m_xData.insert(pa); } return TRUE; } return FALSE; } static BOOL Script2StringArray(const CString& sScript,TCHAR tSpace,CStringArray& arTexts) { //x,y,z,d,a int nPos = -1,nStart = 0; CString sText; while(TRUE) { nPos = sScript.Find(tSpace,nStart); if (nPos != -1) { sText = sScript.Mid(nStart,nPos - nStart); arTexts.Add(sText); nStart = nPos + 1; } else { if (nStart <= sScript.GetLength() - 1) { sText = sScript.Mid(nStart); arTexts.Add(sText); } break; } } return arTexts.GetSize() > 0; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,AcGeMatrix3d& xform) const { if (pszKey != NULL) { std::map::const_iterator it; if ((it = m_xData.find(pszKey)) != m_xData.end()) { TXData xdata = (*it).second; if ( xdata.nVt == (VT_BYREF | VT_R8 + 4)) { CString sText = xdata.pszVal; CStringArray arTexts; Script2StringArray(sText,_T(','),arTexts); if (arTexts.GetSize() == 16) { for (int i = 0;i < 4;i++) { for (int j = 0;j < 4;j++) { xform.entry[i][j] = _ttof(arTexts.GetAt(i * 4 + j)); } } return TRUE; } } } } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,LPCTSTR pszValue) { if (pszKey != NULL) { CString sTmp = pszValue; if(sTmp.GetLength() >= MAX_PATH) return FALSE; if (_tcslen(pszValue) < 0) return FALSE; TXData xdata; memset(&xdata,0,sizeof(xdata)); xdata.nVt = VT_BSTR; xdata.npszLen = _tcslen(pszValue) + 1; xdata.pszVal = new TCHAR[xdata.npszLen]; memset(xdata.pszVal,0,xdata.npszLen); _tcscpy(xdata.pszVal,pszValue); It it = m_xData.find(pszKey); if (it != m_xData.end()) { // mcl add.2010.7.23 原来的要删除 if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL) delete [] (*it).second.pszVal; //(*it).second = xdata; (*it).second.pszVal = new TCHAR[xdata.npszLen]; memset((*it).second.pszVal,0,xdata.npszLen); _tcscpy((*it).second.pszVal,pszValue); delete [] xdata.pszVal; xdata.pszVal = NULL; } else { std::pair pa(pszKey,xdata); m_xData.insert(pa); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,int iIndex,LPCTSTR pszValue) { if (pszKey != NULL) { CString sKey; sKey.Format(_T("%s_%d"),pszKey,iIndex); return SetAt(sKey,pszValue); } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,int iIndex,CString &sValue) { if (pszKey != NULL) { CString sKey; sKey.Format(_T("%s_%d"),pszKey,iIndex); return GetAt(sKey,sValue); } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,int iIndex,const TDbXDataMap& xDataMap) { //{key | type | inf}个隔开 CString sKey,sType,sInfo,sRecord,sText; sText = _T(""); TXData xdata; memset(&xdata,0,sizeof(TXData)); typedef std::map::const_iterator It; for (It it = xDataMap.m_xData.begin(); it != xDataMap.m_xData.end(); ++it) { xdata = (*it).second; sKey = (*it).first; sType = _T(""); sInfo = _T(""); switch (xdata.nVt) { case VT_I4: // 整型 { sType.Format(_T("%d"),VT_I4); sInfo.Format(_T("%d"),xdata.nVal); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case VT_UI4: { sType.Format(_T("%d"),VT_UI4); sInfo.Format(_T("%d"),xdata.nVal); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case VT_UI8: { sType.Format(_T("%d"),VT_UI8); sInfo.Format(_T("%d"),xdata.nVal); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case VT_R8: // 浮点 { sType.Format(_T("%d"),VT_R8); sInfo.Format(_T("%g"),xdata.dVal[0]); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case (VT_BYREF | VT_R8): // 点 { sType.Format(_T("%d"),(VT_BYREF | VT_R8)); sInfo.Format(_T("%.4f,%.4f,%.4f"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case (VT_BYREF | VT_R8 + 1): // cad变化点 { sType.Format(_T("%d"),(VT_BYREF | VT_R8 + 1)); sInfo.Format(_T("%g,%g,%g"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case (VT_BYREF | VT_R8 + 2): // 向量 { sType.Format(_T("%d"),(VT_BYREF | VT_R8 + 2)); sInfo.Format(_T("%g,%g,%g"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case (VT_BYREF | VT_R8 + 3): // 变化向量 { sType.Format(_T("%d"),(VT_BYREF | VT_R8 + 3)); sInfo.Format(_T("%g,%g,%g"),xdata.dVal[0],xdata.dVal[1],xdata.dVal[2]); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case (VT_BYREF | VT_R8 + 4): // 矩阵 { sType.Format(_T("%d"),VT_BYREF | VT_R8 + 4); sInfo.Format(_T("%s"),xdata.pszVal); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } case VT_BSTR: // 字符串 { sType.Format(_T("%d"),VT_BSTR); sInfo.Format(_T("%s"),xdata.pszVal); sRecord.Format(_T("{%s|%s|%s}"),sKey,sType,sInfo); sText += sRecord; break; } break; default: break; } } if (!sText.IsEmpty()) return SetAt(pszKey,iIndex,sText); return FALSE; } BOOL TDbXDataMap::ParseToRecords(CString& sText,CStringArray& arRecords) { CString sRecord; int nFr = 0,nTo = 0; //{Key|Type|Info}... while(TRUE) { nFr = sText.Find(_T("{"),0); nTo = sText.Find(_T("}"),0); if (nFr == 0 && nTo > 0) { sRecord = sText.Mid(nFr,nTo + 1); sRecord.TrimLeft(_T("{")); sRecord.TrimRight(_T("}")); arRecords.Add(sRecord); if (nTo + 1 < sText.GetLength()) { sRecord = sText.Mid(nTo + 1); sText = sRecord; } else { break; } } else { break; } } return arRecords.GetSize() > 0; } BOOL TDbXDataMap::ExtractRecord(CString& sRecord,CString& sKey,CString& sType,CString& sInfo) { //Key|int|Info int nFr = sRecord.Find(_T("|"),0); if (nFr != -1) { CString sTemp; sKey = sRecord.Mid(0,nFr); if (nFr + 1 < sRecord.GetLength()) { sTemp = sRecord.Mid(nFr + 1); sRecord = sTemp; nFr = sRecord.Find(_T("|"),0); if (nFr != -1) { sType = sRecord.Mid(0,nFr); if (nFr + 1 < sRecord.GetLength()) { sInfo = sRecord.Mid(nFr + 1); return TRUE; } } } } return FALSE; } BOOL TDbXDataMap::StringToAcGePoint3d(CString& sText,AcGePoint3d& ptGe) { //x,y,z CString sX,sY,sZ; int nFr = sText.Find(_T(","),0); if (nFr != -1) { CString sTemp; sX = sText.Mid(0,nFr); if (nFr + 1 < sText.GetLength()) { sTemp = sText.Mid(nFr + 1); sText = sTemp; nFr = sText.Find(_T(","),0); if (nFr != -1) { sY = sText.Mid(0,nFr); if (nFr + 1 < sText.GetLength()) { sZ = sText.Mid(nFr + 1); ptGe.set(_ttof(sX),_ttof(sY),_ttof(sZ)); return TRUE; } } } } return FALSE; } BOOL TDbXDataMap::StringToAcGeVector3d(CString& sText,AcGeVector3d& vt) { //x,y,z AcGePoint3d ptGe; if (StringToAcGePoint3d(sText,ptGe)) { vt = ptGe.asVector(); return TRUE; } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,int iIndex,TDbXDataMap& xDataMap) { CString sKey,sType,sInfo,sText,sRecord; AcGePoint3d ptGe; AcGeVector3d vt; BOOL bSuccess = FALSE; AcDbObjectId id; TXData xDat; if (GetAt(pszKey,iIndex,sText)) { sText.TrimLeft(); sText.TrimRight(); if (sText.GetLength() > 1) { CStringArray arRecords; bSuccess = ParseToRecords(sText,arRecords); for (int i = 0;i < arRecords.GetSize();i++) { sRecord = arRecords.GetAt(i); if (ExtractRecord(sRecord,sKey,sType,sInfo)) { int nVt = _ttoi(sType); switch (nVt) { case VT_I4: // 整型 { xDataMap.SetAt(sKey,_ttoi(sInfo)); break; } case VT_UI4: { id.setFromOldId((INT_PTR)_ttoi(sInfo)); xDataMap.SetAt(sKey,id); break; } case VT_UI8: { id.setFromOldId((INT_PTR)_ttoi(sInfo)); xDataMap.SetAt(sKey,id,FALSE); break; } case VT_R8: // 浮点 { xDataMap.SetAt(sKey,_ttof(sInfo)); break; } case (VT_BYREF | VT_R8): // 点 { if (StringToAcGePoint3d(sInfo,ptGe)) { xDataMap.SetAt(sKey,ptGe); } break; } case (VT_BYREF | VT_R8 + 1): // cad变化点 { if (StringToAcGePoint3d(sInfo,ptGe)) { xDataMap.SetAt(sKey,ptGe,TRUE); } break; } case (VT_BYREF | VT_R8 + 2): // 向量 { if (StringToAcGeVector3d(sInfo,vt)) { sKey.Replace(DIF_VT_PT,_T(" ")); sKey.TrimRight(); xDataMap.SetAt(sKey,vt); } break; } case (VT_BYREF | VT_R8 + 3): // 变化向量 { if (StringToAcGeVector3d(sInfo,vt)) { sKey.Replace(DIF_VT_PT,_T(" ")); sKey.TrimRight(); xDataMap.SetAt(sKey,vt,TRUE); } break; } case (VT_BYREF | VT_R8 + 4): //矩阵 { memset(&xDat,0,sizeof(TXData)); xDat.npszLen = sInfo.GetLength() + 1; xDat.pszVal = new TCHAR[xDat.npszLen]; _tcscpy(xDat.pszVal,sInfo); xDataMap.SetAt(sKey,xDat); delete [] xDat.pszVal; break; } case VT_BSTR: // 字符串 { xDataMap.SetAt(sKey,sInfo); break; } break; default: break; } } else { //按照常规处理 xDataMap.SetAt(pszKey,iIndex,sText); bSuccess = TRUE; } } } else { //按照常规处理 xDataMap.SetAt(pszKey,iIndex,sText); bSuccess = TRUE; } } return bSuccess; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,const AcDbObjectId& id,BOOL bIsSoft) { if (pszKey != NULL) { TXData xdata; memset(&xdata,0,sizeof(xdata)); xdata.nVt = VT_UI4; if (!bIsSoft) xdata.nVt = VT_UI8; xdata.nVal = id.asOldId(); It it = m_xData.find(pszKey); if (it != m_xData.end()) { (*it).second = xdata; } else { std::pair pa(pszKey,xdata); m_xData.insert(pa); } return TRUE; } return FALSE; } BOOL TDbXDataMap::SetAt(LPCTSTR pszKey,const TXData& XData) { if (pszKey != NULL) { It it = m_xData.find(pszKey); if (it != m_xData.end()) //找到 { if ( (*it).second.nVt == XData.nVt ) //判断类型相同 { if ( (*it).second.nVt == VT_BSTR || (*it).second.nVt == (VT_BYREF | VT_R8 + 4) ) //字符串特殊处理 { // mcl changed to below 2010.7.23 // if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL) //清空原来的 // { // delete [] (*it).second.pszVal; // } // 重新分配空间赋值 if (XData.npszLen > 0 && XData.pszVal != NULL) { if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL) //清空原来的 delete [] (*it).second.pszVal; (*it).second = XData; (*it).second.pszVal = new TCHAR[XData.npszLen]; memset((*it).second.pszVal,0,XData.npszLen); _tcscpy((*it).second.pszVal,XData.pszVal); } } else { (*it).second = XData; } } } else { if (XData.nVt == VT_BSTR || XData.nVt == (VT_BYREF | VT_R8 + 4)) { SetAt(pszKey,XData.pszVal); } else { std::pair pa(pszKey,XData); m_xData.insert(pa); } } return TRUE; } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,TXData& XData) { if (pszKey != NULL) { std::map::const_iterator it; if ((it = m_xData.find(pszKey)) != m_xData.end()) { XData = (*it).second; return TRUE; } } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,int& nVal) const { if (pszKey != NULL) { std::map::const_iterator it; if ((it = m_xData.find(pszKey)) != m_xData.end()) { TXData xdata = (*it).second; if (xdata.nVt == VT_I4) { nVal = (int)xdata.nVal; return TRUE; } } } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,double& dVal) const { if (pszKey != NULL) { std::map::const_iterator it; if ((it = m_xData.find(pszKey)) != m_xData.end()) { TXData xdata = (*it).second; if (xdata.nVt == VT_R8) { dVal = xdata.dVal[0]; return TRUE; } } } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,AcGeDoubleArray& arVal) const { arVal.setLogicalLength(0); if (pszKey != NULL) { CString sSubKey; double dVal; int nIndex = 0; sSubKey.Format(_T("%s%d"),pszKey,nIndex++); while(GetAt(sSubKey,dVal)) { arVal.append(dVal); sSubKey.Format(_T("%s%d"),pszKey,nIndex++); } } return (arVal.length() > 0); } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,AcGeVector3d& vt) const { /* 由于设置向量是将键值pszkey后增加字符串"$vector3d", 故获取向量时在键值pszkey后增加字符串"$vector3d" */ if (pszKey != NULL) { CString sTmpKey = pszKey; sTmpKey += DIF_VT_PT; std::map::const_iterator it; if ((it = m_xData.find(sTmpKey)) != m_xData.end()) { TXData xdata = (*it).second; if ((xdata.nVt == (VT_BYREF | VT_R8) + 2) || (xdata.nVt == ((VT_BYREF | VT_R8) + 3))) { vt.x = xdata.dVal[0]; vt.y = xdata.dVal[1]; vt.z = xdata.dVal[2]; return TRUE; } } } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,AcGePoint3d& ptGe) const { if (pszKey != NULL) { std::map::const_iterator it; if ((it = m_xData.find(pszKey)) != m_xData.end()) { TXData xdata = (*it).second; if ( (xdata.nVt == (VT_BYREF | VT_R8)) || (xdata.nVt == (VT_BYREF | VT_R8 + 1))) { ptGe.x = xdata.dVal[0]; ptGe.y = xdata.dVal[1]; ptGe.z = xdata.dVal[2]; return TRUE; } } } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,AcGePoint3dArray& arPt) const { arPt.setLogicalLength(0); if (pszKey != NULL) { CString sSubKey; AcGePoint3d pt; int nIndex = 0; sSubKey.Format(_T("%s%d"),pszKey,nIndex++); while(GetAt(sSubKey,pt)) { arPt.append(pt); sSubKey.Format(_T("%s%d"),pszKey,nIndex++); } } return (arPt.length() > 0); } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,CString &sValue) const { if (pszKey != NULL) { std::map::const_iterator it; if ((it = m_xData.find(pszKey)) != m_xData.end()) { TXData xdata = (*it).second; if (xdata.nVt == VT_BSTR || xdata.nVt == (VT_BYREF | VT_R8 + 4) ) { sValue = xdata.pszVal; return TRUE; } } } return FALSE; } BOOL TDbXDataMap::GetAt(LPCTSTR pszKey,AcDbObjectId& id) const { if (pszKey != NULL) { std::map::const_iterator it; if ((it = m_xData.find(pszKey) ) != m_xData.end()) { TXData xdata = (*it).second; if (xdata.nVt == VT_UI4 || xdata.nVt == VT_UI8) { id.setFromOldId(xdata.nVal); return TRUE; } } } return FALSE; } BOOL TDbXDataMap::HasKey(LPCTSTR pszKey,int& nVt) { if (pszKey != NULL) { CString sTmpKey = pszKey; sTmpKey += DIF_VT_PT; if (m_xData.find(pszKey) != m_xData.end()) { TXData xdata = m_xData[pszKey]; nVt = xdata.nVt; return TRUE; } else if( m_xData.find(sTmpKey) != m_xData.end()) { TXData xdata = m_xData[sTmpKey]; nVt = xdata.nVt; return TRUE; } else { return FALSE; } } return FALSE; } void TDbXDataMap::Empty() { m_xData.clear(); } BOOL TDbXDataMap::RemoveAt(LPCTSTR pszKey) { if (pszKey != NULL) { CString sTmpKey = pszKey; sTmpKey += DIF_VT_PT; It it = m_xData.find(pszKey); It it1 = m_xData.find(sTmpKey); if (it != m_xData.end()) { if ( (*it).second.nVt == VT_BSTR || (*it).second.nVt == (VT_BYREF | VT_R8 + 4) ) { if ((*it).second.npszLen > 0 && (*it).second.pszVal != NULL) { delete [] (*it).second.pszVal; } (*it).second.pszVal = NULL; } m_xData.erase(it); //m_xData.clear(); return TRUE; } else if(it1 != m_xData.end()) { if ( (*it1).second.nVt == VT_BSTR || (*it1).second.nVt == (VT_BYREF | VT_R8 + 4) ) { if ((*it1).second.pszVal != NULL) { delete [] (*it1).second.pszVal; } (*it1).second.pszVal = NULL; } m_xData.erase(it1); //m_xData.clear(); return TRUE; } else { return FALSE; } } return FALSE; } BOOL TDbXDataMap::RemoveAt(LPCTSTR pszKey,int nIndex) { if (pszKey != NULL) { CString sKey; sKey.Format(_T("%s_%d"),pszKey,nIndex); return RemoveAt(sKey); } return FALSE; } TDbXDataMap& TDbXDataMap::operator = (const TDbXDataMap& srcMap) { if (this != &srcMap) { //map 互相复制 m_xData.erase(m_xData.begin(),m_xData.end()); m_xData.clear(); CopyFrom(&srcMap); } return *this; } BOOL TDbXDataMap::CopyFrom(const TDbXDataMap* pSrc) { TDbXDataMap* pTDbXDataMap = (TDbXDataMap*) pSrc; if(pTDbXDataMap != NULL && this != pSrc) { //map 互相复制 //m_xData = pSrc->m_xData; m_xData.erase(m_xData.begin(),m_xData.end()); m_xData.clear(); typedef std::map::const_iterator It; for (It it = pSrc->m_xData.begin();it != pSrc->m_xData.end();it++) { if ( (*it).second.nVt == VT_BSTR || (*it).second.nVt == (VT_BYREF | VT_R8 + 4 )) { SetAt( (*it).first,(*it).second); } else { m_xData.insert( (*it) ); } } return TRUE; } return FALSE; } TDbXDataMap::It TDbXDataMap::Begin() { return m_xData.begin(); } TDbXDataMap::ItC TDbXDataMap::Begin() const { return m_xData.begin(); } BOOL TDbXDataMap::GetNext(It& it,TXData& xData) { if (it != m_xData.end()) { xData = (*it).second; ++it; return TRUE; } return FALSE; } BOOL TDbXDataMap::GetNext(ItC& it,TXData& xData) const { if (it != m_xData.end()) { xData = (*it).second; ++it; return TRUE; } return FALSE; } TDbXDataMap::It TDbXDataMap::End() { return m_xData.end(); } TDbXDataMap::ItC TDbXDataMap::End() const { return m_xData.end(); } Acad::ErrorStatus TDbXDataMap::dxfOutFields(AcDbDxfFiler* pFiler) const { if (pFiler == NULL) return Acad::eInvalidInput; TXData xdata; int nVt = -1; AcGePoint3d ptVal; AcGeVector3d vt; AcDbObjectId id; pFiler->writeString(AcDb::kDxfXTextString, MAP_BLOCK_BEGIN); typedef std::map::const_iterator It; for (It it = m_xData.begin(); it != m_xData.end(); ++it) { xdata = (*it).second; nVt = xdata.nVt; pFiler->writeString(AcDb::kDxfXdAsciiString, (LPCTSTR)(*it).first); pFiler->writeInt32(AcDb::kDxfXdInteger32, nVt); switch (nVt) { case VT_I4: // 整型 pFiler->writeInt32(AcDb::kDxfXdInteger32, (int)xdata.nVal); break; case VT_UI4: //s id id.setFromOldId(xdata.nVal); pFiler->writeObjectId(AcDb::kDxfSoftPointerId,id); break; case VT_UI8: //h id id.setFromOldId(xdata.nVal); pFiler->writeObjectId(AcDb::kDxfHardPointerId,id); break; case VT_R8: // 浮点 pFiler->writeDouble(AcDb::kDxfXdReal, xdata.dVal[0]); break; case (VT_BYREF | VT_R8): // 点 ptVal.x = xdata.dVal[0]; ptVal.y = xdata.dVal[1]; ptVal.z = xdata.dVal[2]; pFiler->writePoint3d(AcDb::kDxfXdXCoord, ptVal); break; case (VT_BYREF | VT_R8 + 1): // cad变化点 ptVal.x = xdata.dVal[0]; ptVal.y = xdata.dVal[1]; ptVal.z = xdata.dVal[2]; pFiler->writePoint3d(AcDb::kDxfXdWorldXCoord, ptVal); break; case (VT_BYREF | VT_R8 + 2): // 向量 vt.x = xdata.dVal[0]; vt.y = xdata.dVal[1]; vt.z = xdata.dVal[2]; pFiler->writeVector3d(AcDb::kDxfXdXCoord, vt); break; case (VT_BYREF | VT_R8 + 3): // 变化向量 vt.x = xdata.dVal[0]; vt.y = xdata.dVal[1]; vt.z = xdata.dVal[2]; pFiler->writeVector3d(AcDb::kDxfXdWorldXDir, vt); break; case (VT_BYREF | VT_R8 + 4): // 矩阵 pFiler->writeString(AcDb::kDxfXdAsciiString, (LPCTSTR)xdata.pszVal); break; case VT_BSTR: // 字符串 pFiler->writeString(AcDb::kDxfXdAsciiString, (LPCTSTR)xdata.pszVal); break; default: break; } } pFiler->writeString(AcDb::kDxfXTextString, MAP_BLOCK_END); return Acad::eOk; } Acad::ErrorStatus TDbXDataMap::dxfInFields(AcDbDxfFiler* pFiler) { if (pFiler == NULL) return Acad::eInvalidInput; BOOL bFinded = FALSE; long nVt = 0; TCHAR* pszKey = NULL; TCHAR* pszVal = NULL; AcGePoint3d ptVal; AcGeVector3d vt; CString sKey,sTag; struct resbuf rb; while ((pFiler->readItem(&rb)) == Acad::eOk) { if(rb.restype == AcDb::kDxfXdAsciiString) { sTag = rb.resval.rstring; if (sTag.CompareNoCase(MAP_BLOCK_BEGIN) == 0) { bFinded = TRUE; break; } } } if (!bFinded) return Acad::eOk; int nMapUnitIndex = 0; AcDbObjectId id; while ((pFiler->readItem(&rb)) == Acad::eOk) { nMapUnitIndex++; if(nMapUnitIndex == 1) { if(rb.restype == AcDb::kDxfXdAsciiString) { sKey = rb.resval.rstring; continue; } } else { nMapUnitIndex = 0; } nVt = rb.restype; switch (nVt) { case VT_I4: // 整型 SetAt(sKey,rb.resval.rlong); break; case VT_UI4: //s id #ifdef _WIN64 id.setFromOldId(rb.resval.mnInt64); #else id.setFromOldId(rb.resval.rlong); #endif SetAt(sKey,id); break; case VT_UI8: //h id #ifdef _WIN64 id.setFromOldId(rb.resval.mnInt64); #else id.setFromOldId(rb.resval.rlong); #endif SetAt(sKey,id,FALSE); break; case VT_R8: // 浮点 SetAt(sKey,rb.resval.rreal); break; case (VT_BYREF | VT_R8): // 点 SetAt(sKey, asPnt3d(rb.resval.rpoint)); break; case (VT_BYREF | VT_R8 + 1): // 变化点 SetAt(sKey, asPnt3d(rb.resval.rpoint),TRUE); break; case (VT_BYREF | VT_R8 + 2): // 向量 sKey.Replace(DIF_VT_PT,_T(" ")); sKey.TrimRight(); SetAt(sKey, asPnt3d(rb.resval.rpoint)); break; case (VT_BYREF | VT_R8 + 3): // cad变化向量 sKey.Replace(DIF_VT_PT,_T(" ")); sKey.TrimRight(); SetAt(sKey, asPnt3d(rb.resval.rpoint),TRUE); break; case (VT_BYREF | VT_R8 + 4): //矩阵 SetAt(sKey, rb.resval.rstring); break; case VT_BSTR: // 字符串 SetAt(sKey, rb.resval.rstring); break; default: break; } } return Acad::eOk; } // 增加 clone 的 xdatamap 的关系复制维护lfy 2011-12-6 void TDbXDataMap::BeginCloneXlation(TDbXDataMap* pMapClone,AcDbIdMapping& idMap) const { assert(pMapClone != NULL); AcDbObjectId id; TXData xdata; AcDbIdPair idpair; typedef std::map::const_iterator IT; for (IT it = m_xData.begin();it != m_xData.end();it++) { xdata = (*it).second; switch (xdata.nVt) { case VT_UI4: { id.setFromOldId(xdata.nVal); idpair.setKey(id); if ( idMap.compute(idpair) ) { pMapClone->SetAt((*it).first,idpair.value(),TRUE); } } break; case VT_UI8: { id.setFromOldId(xdata.nVal); idpair.setKey(id); if ( idMap.compute(idpair) ) { pMapClone->SetAt((*it).first,idpair.value(),FALSE); } } break; default: break; } } } Acad::ErrorStatus TDbXDataMap::dwgOutFields(AcDbDwgFiler* pFiler) const { if (pFiler != NULL) { TXData xdata; int nVt = -1; AcGePoint3d ptVal; AcGeVector3d vt; AcDbSoftPointerId id; pFiler->writeString(MAP_BLOCK_BEGIN); typedef std::map::const_iterator It; for (It it = m_xData.begin(); it != m_xData.end(); ++it) { xdata = (*it).second; nVt = xdata.nVt; pFiler->writeString((LPCTSTR)(*it).first); pFiler->writeInt32(nVt); switch (nVt) { case VT_I4: // 整型 pFiler->writeInt32((int)xdata.nVal); break; case VT_UI4: id.setFromOldId(xdata.nVal); pFiler->writeSoftPointerId(id); break; case VT_UI8: id.setFromOldId(xdata.nVal); pFiler->writeHardPointerId(id); break; case VT_R8: // 浮点 pFiler->writeDouble(xdata.dVal[0]); break; case (VT_BYREF | VT_R8): // 点 case (VT_BYREF | VT_R8 + 1): ptVal.x = xdata.dVal[0]; ptVal.y = xdata.dVal[1]; ptVal.z = xdata.dVal[2]; pFiler->writePoint3d(ptVal); break; case (VT_BYREF | VT_R8 + 2): // 向量 case (VT_BYREF | VT_R8 + 3): vt.x = xdata.dVal[0]; vt.y = xdata.dVal[1]; vt.z = xdata.dVal[2]; pFiler->writeVector3d(vt); break; case (VT_BYREF | VT_R8 + 4): //矩阵 pFiler->writeString(xdata.pszVal); break; case VT_BSTR: // 字符串 pFiler->writeString(xdata.pszVal); break; default: break; } } pFiler->writeString(MAP_BLOCK_END); return Acad::eOk; } return Acad::eInvalidInput; } Acad::ErrorStatus TDbXDataMap::dwgInFields(AcDbDwgFiler* pFiler) { if (pFiler == NULL) return Acad::eInvalidInput; BOOL bFinded = FALSE; Adesk::Int32 nVt = 0; TXData xdata; TCHAR* pszKey = NULL; TCHAR* pszVal = NULL; AcGePoint3d ptVal; AcGeVector3d vt; CString sKey,sTag; m_xData.erase(m_xData.begin(),m_xData.end()); m_xData.clear(); while ((pFiler->readString(&pszVal)) == Acad::eOk) { sTag = pszVal; if (pszVal != NULL) acutDelString(pszVal); if (sTag.CompareNoCase(MAP_BLOCK_BEGIN) == 0) { bFinded = TRUE; break; } } if (!bFinded) return Acad::eOk; while ((pFiler->readString(&pszKey)) == Acad::eOk) { sKey = pszKey; if (pszKey != NULL) acutDelString(pszKey); if (sKey.CompareNoCase(MAP_BLOCK_END) == 0) { break; } pFiler->readInt32(&nVt); xdata.nVt = (int)nVt; AcDbSoftPointerId id; AcDbHardPointerId idh; switch (nVt) { case VT_I4: // 整型 pFiler->readInt32(&nVt); xdata.nVal = (int)nVt; SetAt(sKey, (int)xdata.nVal); break; case VT_UI4: pFiler->readSoftPointerId(&id); SetAt(sKey,id); break; case VT_UI8: pFiler->readHardPointerId(&idh); SetAt(sKey,idh,FALSE); break; case VT_R8: // 浮点 pFiler->readDouble(&xdata.dVal[0]); SetAt(sKey, xdata.dVal[0]); break; case (VT_BYREF | VT_R8): // 点 pFiler->readPoint3d(&ptVal); SetAt(sKey, ptVal); break; case (VT_BYREF | VT_R8 + 1): // cad变化点 pFiler->readPoint3d(&ptVal); SetAt(sKey, ptVal, TRUE); break; case (VT_BYREF | VT_R8 + 2): // 向量 pFiler->readVector3d(&vt); sKey.Replace(DIF_VT_PT,_T(" ")); sKey.TrimRight(); SetAt(sKey, vt); break; case (VT_BYREF | VT_R8 + 3): // cad变化向量 pFiler->readVector3d(&vt); sKey.Replace(DIF_VT_PT,_T(" ")); sKey.TrimRight(); SetAt(sKey, vt, TRUE); break; case (VT_BYREF | VT_R8 + 4): //矩阵 pszVal = NULL; pFiler->readString(&pszVal); SetAt(sKey, pszVal); if (pszVal != NULL) acutDelString(pszVal); break; case VT_BSTR: // 字符串 pszVal = NULL; pFiler->readString(&pszVal); SetAt(sKey, pszVal); if (pszVal != NULL) acutDelString(pszVal); break; default: break; } } return Acad::eOk; } // bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典 BOOL TDbXDataMap::XDMap2Resbuf(LPCTSTR pszApp, struct resbuf*& pRb,BOOL bXRecord) { if(pszApp == NULL || m_xData.empty()) return FALSE; struct resbuf* pTemp = NULL; // 链表头 if (!bXRecord) { // 扩展数据需要链表头 pTemp = acutNewRb(AcDb::kDxfRegAppName); acutNewString(pszApp,pTemp->resval.rstring); pRb = pTemp; } AcDbObjectId id; ads_name adsName; struct resbuf* pTempNext = NULL; typedef std::map::const_iterator IT; // 遍历map for(IT iter = m_xData.begin(); iter != m_xData.end(); iter++) { pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(iter->first, pTempNext->resval.rstring); if (pRb == NULL) { pRb = pTempNext; } else { pTemp->rbnext = pTempNext; } pTemp = pTempNext; pTempNext = NULL; switch (iter->second.nVt) { case VT_I4: // 整型 pTempNext = acutNewRb(AcDb::kDxfXdInteger32); pTempNext->resval.rlong = (long)iter->second.nVal; pTemp->rbnext = pTempNext; break; /*--------------------------------------------------------------------------------------- Extended data (xdata) is created by applications written with ObjectARX? or AutoLISP? and can be added to any object. Xdata consists of a linked list of resbufs used by the application. (AutoCAD maintains the information but doesn't use it.) The data is associated with a DXF group code in the range of 1000 to 1071. */ /* so someguy want save id to an entity xdata ,must save as kDxfXdHandle kDxfXdHandle is same as string; */ case VT_UI4: //s id not support xdata id.setFromOldId(iter->second.nVal); acdbGetAdsName(adsName,id); if(bXRecord) pTempNext = acutBuildList(AcDb::kDxfSoftPointerId, adsName, 0); else { pTempNext = acutNewRb(AcDb::kDxfXdHandle); TCHAR szHandleStr[19]; memset(szHandleStr,0,sizeof(szHandleStr) ); id.handle().getIntoAsciiBuffer(szHandleStr); #if ADS < 17 acutNewString(szHandleStr, pTempNext->resval.rstring); #else acutNewString(pTempNext->resval.rstring, (int)(_tcslen(szHandleStr) + 1)); _tcscpy(pTempNext->resval.rstring,szHandleStr); #endif } pTemp->rbnext = pTempNext; break; case VT_UI8: //h id not support xdata id.setFromOldId(iter->second.nVal); acdbGetAdsName(adsName,id); if(bXRecord) pTempNext = acutBuildList(AcDb::kDxfHardPointerId, adsName, 0); else { pTempNext = acutNewRb(AcDb::kDxfXdHandle); TCHAR szHandleStr[19]; memset(szHandleStr,0,sizeof(szHandleStr) ); id.handle().getIntoAsciiBuffer(szHandleStr); #if ADS < 17 acutNewString(szHandleStr, pTempNext->resval.rstring); #else acutNewString(pTempNext->resval.rstring, (int)(_tcslen(szHandleStr) + 1)); _tcscpy(pTempNext->resval.rstring,szHandleStr); #endif } pTemp->rbnext = pTempNext; //--------------------------------------------------------------------------------- break; case VT_BSTR: // 字符串 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(iter->second.pszVal, pTempNext->resval.rstring); pTemp->rbnext = pTempNext; break; case VT_R8: // 浮点型 pTempNext = acutNewRb(AcDb::kDxfXdReal); pTempNext->resval.rreal = iter->second.dVal[0]; pTemp->rbnext = pTempNext; break; case (VT_BYREF | VT_R8): // 点 pTempNext = acutNewRb(AcDb::kDxfXdXCoord); pTempNext->resval.rpoint[0] = iter->second.dVal[0]; pTempNext->resval.rpoint[1] = iter->second.dVal[1]; pTempNext->resval.rpoint[2] = iter->second.dVal[2]; pTemp->rbnext = pTempNext; break; case (VT_BYREF | VT_R8 + 1): // 随cad实体变化的点 pTempNext = acutNewRb(AcDb::kDxfXdWorldXCoord); pTempNext->resval.rpoint[0] = iter->second.dVal[0]; pTempNext->resval.rpoint[1] = iter->second.dVal[1]; pTempNext->resval.rpoint[2] = iter->second.dVal[2]; pTemp->rbnext = pTempNext; break; case (VT_BYREF | VT_R8 + 2): // 向量 pTempNext = acutNewRb(AcDb::kDxfXdXCoord); pTempNext->resval.rpoint[0] = iter->second.dVal[0]; pTempNext->resval.rpoint[1] = iter->second.dVal[1]; pTempNext->resval.rpoint[2] = iter->second.dVal[2]; pTemp->rbnext = pTempNext; break; case (VT_BYREF | VT_R8 + 3): // 随cad实体变化的向量 pTempNext = acutNewRb(AcDb::kDxfXdWorldXDir); pTempNext->resval.rpoint[0] = iter->second.dVal[0]; pTempNext->resval.rpoint[1] = iter->second.dVal[1]; pTempNext->resval.rpoint[2] = iter->second.dVal[2]; pTemp->rbnext = pTempNext; break; case (VT_BYREF | VT_R8 + 4): // 矩阵 pTempNext = acutNewRb(AcDb::kDxfXdAsciiString); acutNewString(iter->second.pszVal, pTempNext->resval.rstring); pTemp->rbnext = pTempNext; break; default: break; } pTemp = pTempNext; pTempNext = NULL; } return (pRb != NULL); } // bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典 BOOL TDbXDataMap::Resbuf2XDMap(struct resbuf* pRb,BOOL bXRecord,AcDbDatabase* pDb) { if(pRb == NULL) return FALSE; m_xData.clear(); struct resbuf* pTemp = pRb; // 跳过扩展数据头 扩展数据 if (!bXRecord) { pTemp = pRb->rbnext; } AcDbObjectId id; int nMapUnitIndex = 1; TXData xData; CString sTemp; while (pTemp != NULL) { if (nMapUnitIndex == 1) { // skey键值 if (pTemp->restype == AcDb::kDxfXdAsciiString) { sTemp = pTemp->resval.rstring; nMapUnitIndex++; } } else { // value switch (pTemp->restype) { case AcDb::kDxfXdAsciiString: // 字符串 xData.nVt = VT_BSTR; xData.npszLen = _tcslen(pTemp->resval.rstring) + 1; xData.pszVal = new TCHAR[xData.npszLen]; _tcscpy(xData.pszVal,pTemp->resval.rstring); nMapUnitIndex++; break; case AcDb::kDxfXdInteger32: // 整型 xData.nVt = VT_I4; xData.nVal = pTemp->resval.rlong; nMapUnitIndex++; break; /*--------------------------------------------------------------------------------------- Extended data (xdata) is created by applications written with ObjectARX? or AutoLISP? and can be added to any object. Xdata consists of a linked list of resbufs used by the application. (AutoCAD maintains the information but doesn't use it.) The data is associated with a DXF group code in the range of 1000 to 1071. */ case AcDb::kDxfSoftPointerId: //s id not support xdata acdbGetObjectId(id, pTemp->resval.rlname); xData.nVt = VT_UI4; xData.nVal = id.asOldId(); nMapUnitIndex++; break; case AcDb::kDxfHardPointerId: //h id not support xdata acdbGetObjectId(id, pTemp->resval.rlname); xData.nVt = VT_UI8; xData.nVal = id.asOldId(); nMapUnitIndex++; break; //-------------------------------------------------------------------------------------- case AcDb::kDxfXdHandle: //handle for xdata { AcDbHandle handle(pTemp->resval.rstring); if (pDb == NULL) pDb = acdbCurDwg(); if (pDb != NULL) { if ( Acad::eOk == pDb->getAcDbObjectId(id,false,handle) ) { xData.nVt = VT_UI4; xData.nVal = id.asOldId(); nMapUnitIndex++; } } } break; case AcDb::kDxfXdReal: // 浮点型 xData.nVt = VT_R8; xData.dVal[0] = pTemp->resval.rreal; nMapUnitIndex++; break; case AcDb::kDxfXdXCoord: // 点 向量 xData.nVt = (VT_BYREF | VT_R8); xData.dVal[0] = pTemp->resval.rpoint[0]; xData.dVal[1] = pTemp->resval.rpoint[1]; xData.dVal[2] = pTemp->resval.rpoint[2]; nMapUnitIndex++; if(sTemp.Find(DIF_VT_PT) >= 0) { // 向量 xData.nVt = (VT_BYREF | VT_R8 + 2); } break; case AcDb::kDxfXdWorldXCoord: // 随cad实体变化的点 xData.nVt = (VT_BYREF | VT_R8 + 1); xData.dVal[0] = pTemp->resval.rpoint[0]; xData.dVal[1] = pTemp->resval.rpoint[1]; xData.dVal[2] = pTemp->resval.rpoint[2]; nMapUnitIndex++; break; case AcDb::kDxfXdWorldXDir: // 随cad实体变化的向量 xData.nVt = (VT_BYREF | VT_R8 + 3); xData.dVal[0] = pTemp->resval.rpoint[0]; xData.dVal[1] = pTemp->resval.rpoint[1]; xData.dVal[2] = pTemp->resval.rpoint[2]; nMapUnitIndex++; break; default: break; } } if(nMapUnitIndex > 2) { // 插入一套 skey value std::pair pa(sTemp,xData); m_xData.insert(pa); nMapUnitIndex = 1; } pTemp = pTemp->rbnext; } return !m_xData.empty(); } //支持扩展数据的4个方法 // 根据实体指针插入链表 bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典 BOOL TDbXDataMap::Write(AcDbObject* pEnt, LPCTSTR pszApp, BOOL bXRecord) { if (pEnt == NULL || pszApp == NULL) return FALSE; // 根据map生成链表 struct resbuf* pRb = NULL; if (!XDMap2Resbuf(pszApp ,pRb ,bXRecord)) return FALSE; Acad::ErrorStatus eStat = Acad::eOutOfMemory; if (!bXRecord) { // 扩展数据 struct resbuf* pTmpRb = pEnt->xData(pszApp); if (pTmpRb != NULL) { // 存在清空 struct resbuf* pTmp = acutNewRb(AcDb::kDxfRegAppName); pEnt->setXData(pTmp); acutRelRb(pTmpRb); acutRelRb(pTmp); } // 注册扩展数据链表 acdbRegApp(pszApp); eStat = pEnt->setXData(pRb); acutRelRb(pRb); return (eStat == Acad::eOk); } // 扩展词典 AcDbObjectId dictObjId, xrecObjId; pEnt->createExtensionDictionary(); dictObjId = pEnt->extensionDictionary(); // 打开扩展词典指针 AcDbDictionary* pDict = NULL; if (Acad::eOk != acdbOpenObject(pDict, dictObjId, AcDb::kForWrite)) { if (pRb != NULL) acutRelRb(pRb); return FALSE; } AcDbXrecord* pXrec = NULL; if (pDict->has(pszApp)) { // 存在此扩展词典 获取扩展词典指针 AcDbObject* pObj = NULL; pDict->getAt(pszApp,pObj,AcDb::kForWrite); if(pObj != NULL) { pXrec = AcDbXrecord::cast(pObj); if(pXrec != NULL) { // 重新设置扩展词典 pXrec->setFromRbChain(*pRb); } pObj->close(); } pDict->close(); } else { // 不存在此扩展词典 pXrec = new AcDbXrecord; eStat = pXrec->setFromRbChain(*pRb); pDict->setAt(pszApp,pXrec,xrecObjId); pXrec->close(); pDict->close(); } acutRelRb(pRb); return (eStat == Acad::eOk); } // 根据实体id插入链表 bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典 BOOL TDbXDataMap::Write(const AcDbObjectId& id,LPCTSTR pszApp,BOOL bXRecord) { if(pszApp == NULL) return FALSE; AcDbEntity * pEnt = NULL; BOOL bWriteIdXData = FALSE; if(Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite)) { // 根据实体指针设置链表 bWriteIdXData = Write(pEnt,pszApp,bXRecord); pEnt->close(); } return bWriteIdXData; } // bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典 BOOL TDbXDataMap::Read(AcDbObject* pEnt,LPCTSTR pszApp,BOOL bXRecord) { if(pEnt == NULL || pszApp == NULL) return FALSE; struct resbuf* pRb = NULL; BOOL bResbuf2XDmap = FALSE; if (!bXRecord) { // 扩展数据 pRb = pEnt->xData(pszApp); if(pRb == NULL) return FALSE; bResbuf2XDmap = Resbuf2XDMap(pRb,bXRecord,pEnt->database()); acutRelRb(pRb); return bResbuf2XDmap; } // 获取扩展数据(词典)id AcDbObjectId dictObjId, xrecObjId; dictObjId = pEnt->extensionDictionary(); if (dictObjId.isNull()) { // 没有扩展数据 return FALSE; } // 打开扩展词典实体 AcDbDictionary* pDict = NULL; if (Acad::eOk != acdbOpenObject(pDict, dictObjId, AcDb::kForRead)) { return FALSE; } AcDbXrecord *pXrec = NULL; AcDbObject* pObj = NULL; // 获取扩展数据链表 if (Acad::eOk == pDict->getAt(pszApp,pObj,AcDb::kForRead)) { pXrec = AcDbXrecord::cast(pObj); if (pXrec != NULL) { pXrec->rbChain(&pRb); if (pRb != NULL) { bResbuf2XDmap = Resbuf2XDMap(pRb,bXRecord,pEnt->database()); acutRelRb(pRb); } } pObj->close(); } else { // 获取链表失败 pDict->close(); return FALSE; } pDict->close(); return bResbuf2XDmap; } // bXRecord = fase 操作扩展数据 bXRecord = true 操作扩展词典 BOOL TDbXDataMap::Read(const AcDbObjectId& id,LPCTSTR pszApp,BOOL bXRecord) { AcDbEntity * pEnt = NULL; BOOL bReadIdXData = FALSE; if(Acad::eOk == acdbOpenAcDbEntity(pEnt, id, AcDb::kForRead)) { bReadIdXData = Read(pEnt,pszApp,bXRecord); pEnt->close(); } return bReadIdXData; }