1 說明
在AutoCAD每個圖形資料庫中都包含一個有名對象字典,在該字典中包含了組、圖層、材料、顔色、布局和列印資訊等,如下圖所示。例如,如果在AutoCAD中用GROUP指令建立了一個組實體,由組成特定組的相關實體的組對象(AcDbGroup)将置于有名對象字典中。組記錄由組名構成,為一個AcDbGroup對象的映像。需要在有名對象字典中儲存自定義資料時,應首先在根字典下新增一個新的字典,然後将資料儲存在新添加的字典中。這樣可以避免與字典的基本對象混淆。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPR10MVpmTy0kaNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zROBlL5IDNxUzMyYTMxIjMwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2 相關函數
在有名對象字典添加資料用到AcDbDictionary類的getAt()、setAt()等函數,其用法與在擴充字典中添加資料時相同。唯一的差別在于擷取字典的方式上,擴充字典是屬于特定實體(AcDbObject類),有名對象字典屬于圖形資料庫( AcDbDatabase類)。是以,擷取有名對象字典需要用到AcDbDatabase類的函數。
getNamedObjectsDictionary()
- 定義:
Acad::ErrorStatus getNamedObjectsDictionary(
AcDbDictionary*& pDict,
AcDb::OpenMode mode
);
-
參數:
pDict —— 傳回指向有名對象字典的指針;
OpenMode mode —— 打開有名對象字典的模式。
- 作用:以指定的模式打開圖形資料庫的有名對象字典。 指針pDict傳回有名對象字典的位址。
- 傳回值:如果打開成功,則傳回Acad :: eOk。
getXXXXXDictionary()
函數名稱中“XXXXX”可以用“Color ”、“Group”、“Layout”、“Material”等字元串替代,以擷取圖形資料庫的顔色、組、圖層、材料等字典。
- 定義:
Acad::ErrorStatus getXXXXXDictionary(
AcDbDictionary*& pDict,
AcDb::OpenMode mode
);
-
參數:
pDict —— 傳回指向“XXXXX”字典的指針;
OpenMode mode —— 打開“XXXXX”字典的模式。
- 作用:以指定的模式打開圖形資料庫的“XXXXX”字典。 指針pDict傳回“XXXXX”字典的位址。
- 傳回值:如果打開成功,則傳回Acad :: eOk。
3 思路
3.1 在有名對象字典中添加字典
在圖形資料庫的有名對象字典中添加一個字典,可以按以下步驟:
- 使用getNamedObjectsDictionary()函數擷取有名對象字典;
- 然後通過使用setAt()函數在有名對象字典添加一個字典;
- 使用setAt()函數在新增字典中添加對象。
這樣就完成了為有名對象字典添加字典的工作。
3.2 在有名對象字典中檢視字典
在圖形資料庫的有名對象字典中檢視一個字典,可以按以下步驟:
- 使用getNamedObjectsDictionary()函數擷取有名對象字典;
- 然後通過使用getAt()函數擷取指定名稱的字典;
- 使用getAt()函數指定名稱的字典中擷取自定名稱的對象。
這樣就完成了在有名對象字典中檢視字典的工作。
3.3 從有名對象字典中删除字典
在圖形資料庫的有名對象字典中删除一個字典,可以按以下步驟:
- 使用getNamedObjectsDictionary()函數擷取有名對象字典;
- 然後通過使用remove()函數删除指定名稱的字典;
這樣就完成了在有名對象字典中删除字典的工作。
4 步驟
在有名對象字典中添加一個新的字典,代碼如下:
//在有名對象字典中添加字典
static void MyGroupcreateDict()
{
//提示使用者輸入要添加的字典的名稱
TCHAR DictName[200], objString[200];
DictName[0] = objString[0] = _T('\0');
acedGetString(NULL, _T("Enter Dictionary name: "), DictName);
acedGetString(NULL, _T("Enter Object Name to be added: "), objString);
//擷取目前圖形資料庫的有名對象字典
AcDbObjectId objId;
AcDbDictionary *pNameObjDict = NULL, *pDict = NULL;
acdbHostApplicationServices() -> workingDatabase()-> getNamedObjectsDictionary(pNameObjDict,AcDb::kForWrite);
//在目前有名對象字典中添加一個字典
if(pNameObjDict -> getAt(DictName,(AcDbObject *&)pDict,AcDb::kForWrite) == Acad::eKeyNotFound)
{
pDict = new AcDbDictionary;
pNameObjDict -> setAt(DictName, pDict, objId);
pDict -> close();
}
pNameObjDict -> close();
//在新添加的字典中添加對象
AcDbObject* pObj = NULL;
if ((pObj = selectObject(AcDb::kForWrite)) == NULL)
{
return;
}
if ((acdbOpenObject(pDict,objId, AcDb::kForWrite) == Acad::eOk ))
{
pDict -> setAt(objString,pObj,objId);
}
pObj -> close();
pDict -> close();
}
檢視有名對象字典中的字典,代碼如下:
//檢視添加的字典
static void MyGroupviewDict()
{
//提示使用者輸入要添加的字典的名稱
TCHAR DictName[200];
DictName[0] = _T('\0');
acedGetString(NULL, _T("Enter Dictionary name: "), DictName);
//擷取字典
AcDbObjectId objId;
AcDbDictionary *pNameObjDict = NULL, *pDict = NULL;
acdbHostApplicationServices() -> workingDatabase()-> getNamedObjectsDictionary(pNameObjDict,AcDb::kForRead);
if (pNameObjDict -> getAt(DictName, (AcDbObject *&)pDict, AcDb::kForRead) == Acad::eKeyNotFound )
{
acutPrintf(_T("\nDictionary %s donot exist!"),DictName);
return;
}
pNameObjDict -> close();
//擷取字典中的對象
AcDbObject *pObj = NULL;
TCHAR objStr[200];
objStr[0] = _T('\0');
acedGetString(NULL, _T("Enter Object name: "), objStr);
if (pDict -> getAt(objStr, (AcDbObject *&)pObj, AcDb::kForRead) == Acad::eOk)
{
acutPrintf(_T("\n Object ID: %d"), pObj -> objectId());
acutPrintf(_T("\n Object Name:%s"), pObj->isA()->name());
}
pObj -> close();
pDict -> close();
}
删除有名對象字典中的字典,代碼如下:
//删除字典
static void MyGroupdeleteDict()
{
//提示使用者輸入要添加的字典的名稱
TCHAR DictName[200];
DictName[0] = _T('\0');
acedGetString(NULL, _T("Enter Dictionary name: "), DictName);
//擷取字典
AcDbDictionary *pNameObjDict = NULL;
acdbHostApplicationServices() -> workingDatabase()-> getNamedObjectsDictionary(pNameObjDict, AcDb::kForWrite);
Acad::ErrorStatus es;
es = pNameObjDict -> remove(DictName);
if ( es == Acad::eOk)
{
acutPrintf(_T("\n Delete Dictionary %s successfully!"), DictName);
}
else if(es == Acad::eKeyNotFound)
{
acutPrintf(_T("\n Dictionary %s donot exist!"), DictName);
}
else
{
acutPrintf(_T("\n Dictionary %s Name is Invalid!"), DictName);
}
pNameObjDict -> close();
}
還要添加一用于提示使用者選擇實體的函數,代碼如下:
//提示使用者選擇實體
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;
}
5 效果
使用AutoCAD2016建立一個檔案,圖形資料庫的有名對象字典如下:
用上述代碼生成的程式在有名對象字典中建立一個新的字典,将圖中直線添加到字典中,可以檢視添加的字典中的實體,如下圖所示:
删除添加的字典後,圖形資料庫的有名對象字典恢複原樣,如下圖所示:
6 源代碼
源代碼:NamedObjDic
提取碼:xll8
參考文檔
[1]:Autodesk ObjectARX for AutoCAD 2015: Developer Guide.