Opening and Closing Database Objects

Each AcDbObject object can be referred to in three different ways:

When AutoCAD is not running, the drawing is stored in the file system. Objects contained in a DWG file are identified by their handles.

After the drawing is opened, the drawing information is accessible through the AcDbDatabase object. Each object in the database has an object ID, which persists throughout the current edit session, from creation until deletion of the AcDbDatabase in which the object resides. The open functions take an object ID as an argument and return a pointer to an AcDbObject object. This pointer is valid until the object is closed, as shown in the following figure.

You can open an object using the acdbOpenObject() global function.

You can map a handle to an object ID using the getAcDbObjectId() function.

You can also open an object and then request its handle:

AcDbObject* pObject;
AcDbHandle handle;
pObject->getAcDbHandle(handle);
Note: Whenever a database object is opened, it should be closed at the earliest possible opportunity. You can use the AcDbObject::close() function to close a database object.

An ads_name is equivalent to an AcDbObjectId. The AcDb library provides two standalone functions that allow you to translate between an AcDbObjectId and an ads_name:

// Returns an ads_name for a given object ID.
//
acdbGetAdsName(ads_name& objName,
               AcDbObjectId objId); 
// Returns an object ID for a given ads_name.
//
acdbGetObjectId(AcDbObjectId& objId,
                ads_name objName); 

Generally, you obtain an object through a selection, and it is returned in ads_name form. You then need to exchange the ads_name for an AcDbObjectId and open it. The following function demonstrates this process:

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.
    //
    acdbGetObjectId(eId, en);
    AcDbEntity * pEnt;
    acdbOpenObject(pEnt, eId, openMode);
    return pEnt;
}

You can open an object in one of three modes:

The following table shows the error codes returned when you attempt to open an object in different modes and the object is already open.

Opening objects in different modes 

     

Object already opened for:

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)

If you are trying to open an object for write and you receive an error eWasOpenForRead, you can use upgradeOpen() to upgrade the open status to write if there is only one reader of the object. Then you would use downgradeOpen() to downgrade its status to read. Similarly, if your object is open for notify—for example, when you are receiving notification—and you want to open it for write, you can use upgradeFromNotify() to upgrade its open status to write. Then you would use downgradeToNotify() to downgrade its status to notify.

For more information about how to manage complex sequences of opening and closing objects, see the "Transaction Manager" section.