一、AcDbObject對象對象的通路方式
在ObjectARX中,每個AcDbObject對象可以通過三種方式進行通路:
- 通過其句柄
- 通過其ID
- 通過其C++執行個體指針
當AutoCAD沒有運作,圖紙儲存在檔案系統中時,可以通過句柄來辨別DWG檔案中的對象;當圖紙打開以後,圖紙資訊可通過AcDbDatabase對象進行通路。每一個資料庫中的對象擁有一個ID,其生存期持續于AcDbDatabase對象建立和删除之間的時期。打開函數(例如acdbOpenObject()函數)根據對象的ID打開對象,并傳回對象的指針。當對象關閉後,這個指針随即失效。
上述關系如下圖所示。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiYTMfhHLlN3XnxCM38FdsYkRGZkRG9lcvx2bjxSNx8VZ6l2cs0TP35kMJR0T0kEVllnRXJWQClGVF5UMR9Fd4VGdsATNfd3bkFGazxycykFaKdkYzZUbapXNXlleSdVY2pESa9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL5M2N5IGN0kDO5IDZ3kDN4UzN3QTN1gDMxcjZmRjY3Q2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
二、ID→句柄的轉換
法1:AcDbDatabase::getAcDbObjectId(),根據對象ID值擷取其句柄。
Acad::ErrorStatus getAcDbObjectId(
AcDbObjectId& retId,
bool createIfNotFound,
const AcDbHandle& objHandle,
Adesk::UInt32 xRefId = 0
);
法2:打開一個對象後通過getAcDbHandle()方法擷取句柄
AcDbObject* pObject;
AcDbHandle handle;
pObject->getAcDbHandle(handle);
請注意:打開對象以後,請盡快關閉。可以使用AcDbObject::close() 函數去關閉一個資料庫對象。
三、對象ads_name→對象ID→對象指針
ads_name和AcDbObjectId是等價的。AcDb庫提供了兩個标準函數來實作AcDbObjectId和ads_name的轉換。
// Returns an ads_name for a given object ID.
// 根據指定ID傳回其ads_name
acdbGetAdsName(ads_name& objName, AcDbObjectId objId);
// Returns an object ID for a given ads_name.
// 根據指定ads_name傳回其ID
acdbGetObjectId(AcDbObjectId& objId, ads_name objName);
通常,你是通過選擇集擷取對象,而選擇集傳回的是對象的ads_name。此時,你需要将ads_name轉換為ID值,然後利用acdbOpenObject 全局函數打開對象。
以下函數描述了這個過程
AcDbEntity*
selectEntity(AcDbObjectId& eId, AcDb::OpenMode openMode)
{
ads_name en;
ads_point pt;
acedEntSel("\nSelect an entity: ", en, pt);
// Exchange the ads_name for an object ID.
// 更換ads_name為ID值
acdbGetObjectId(eId, en);
AcDbEntity * pEnt;
acdbOpenObject(pEnt, eId, openMode);
return pEnt;
}
四、對象打開模式說明
acdbOpenObject可以三種模式打開對象,分别為:
- kForRead:如果對象沒有用kForWrite或者kForNotify方式打開,該模式可以被打開為讀模式,且最多可以被256個讀者讀取。
- kForWrite:如果對象沒有被打開,則該模式可将對象打開為寫模式。
- kForNotify:當對象關閉、打開為讀模式、打開為寫模式時,該模式均可以打開為通知模式。程式中極少需要将一個對象打開為通知模式。
以下表格描述了當對象打開後,再次以不同模式打開時傳回的錯誤代碼。
已經打開為 | 再次打開為 | 再次打開為 | 再次打開為 |
---|---|---|---|
kForRead | kForWrite | kForNotify | |
openedForRead | eAtMaxReaders (if readCount = 256; otherwise succeeds) | eWasOpenForRead | (Succeeds) |
openedForWrite | eWasOpenForWrite | eWasOpenForWrite | (Succeeds) |
openedForNotify | eWasOpenForNotify | eWasOpenForNotify | eWasOpenForNotify |
wasNotifying | (Succeeds) | eWasNotifying | eWasNotifying |
Undo | eWasOpenForUndo | eWasOpenForUndo | (Succeeds) |
當你試圖用寫模式打開一個對象時,函數傳回錯誤提示“eWasOpenForRead”,你可以用upgradeOpen() 更新原對象的讀模式為寫模式(如果對象隻有一個讀取者)。當寫完對象以後,調用downgradeOpen()函數将對象打開模式降級為讀模式。相似的,如果對象已經以通知模式打開,但你想更新為寫模式,可以調用函數upgradeFromNotify()進行更新;當使用完畢後,調用downgradeToNotify()去降級為通知模式。