天天看點

ObjectARX開發筆記(四)——有名對象字典1 說明2 相關函數3 思路4 步驟5 效果6 源代碼

1 說明

在AutoCAD每個圖形資料庫中都包含一個有名對象字典,在該字典中包含了組、圖層、材料、顔色、布局和列印資訊等,如下圖所示。例如,如果在AutoCAD中用GROUP指令建立了一個組實體,由組成特定組的相關實體的組對象(AcDbGroup)将置于有名對象字典中。組記錄由組名構成,為一個AcDbGroup對象的映像。需要在有名對象字典中儲存自定義資料時,應首先在根字典下新增一個新的字典,然後将資料儲存在新添加的字典中。這樣可以避免與字典的基本對象混淆。

ObjectARX開發筆記(四)——有名對象字典1 說明2 相關函數3 思路4 步驟5 效果6 源代碼

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建立一個檔案,圖形資料庫的有名對象字典如下:

ObjectARX開發筆記(四)——有名對象字典1 說明2 相關函數3 思路4 步驟5 效果6 源代碼

用上述代碼生成的程式在有名對象字典中建立一個新的字典,将圖中直線添加到字典中,可以檢視添加的字典中的實體,如下圖所示:

ObjectARX開發筆記(四)——有名對象字典1 說明2 相關函數3 思路4 步驟5 效果6 源代碼

删除添加的字典後,圖形資料庫的有名對象字典恢複原樣,如下圖所示:

ObjectARX開發筆記(四)——有名對象字典1 說明2 相關函數3 思路4 步驟5 效果6 源代碼

6 源代碼

源代碼:NamedObjDic

提取碼:xll8

參考文檔

[1]:Autodesk ObjectARX for AutoCAD 2015: Developer Guide.

繼續閱讀