Finding Properties for an AutoCAD Object

Finding all applicable IPropertyManager interfaces from an AutoCAD object's IUnknown pointer requires several steps, as outlined in the following procedure.

To find an AutoCAD entity's IPropertyManager interfaces

Query the object for the IAcadBaseObject interface:

IAcadBaseObject* pBase = NULL;
if (FAILED(pObjUnkArray[i]->QueryInterface(IID_IAcadBaseObject,
    reinterpret_cast<LPVOID*>(&pBase))))
return E_FAIL;

Use the IAcadBaseObject pointer to get the object ID:

AcDbObjectId objectID = NULL;
if (FAILED(pBase->GetObjectId(&objectID))) {
pBase->Release();
return E_FAIL;
}

Open the AutoCAD entity represented by the object:

AcDbEntity* pEnt = NULL;
if (Acad::eOk != acadbOpenAcDbEntity(pEnt, objectID,
    AcDb::kForRead, Adesk::kTrue))
return E_FAIL;

Get the entity's AcRxClass by calling AcRxObject::isA() on the entity pointer:

AcRxClass* pClass = pEnt->isA();

Declare a new COleSafeArray object to contain your pointers and an index variable:

COleSafeArray PropMgrArray;
long n;

The remaining steps are iterated in a loop that traverses the object's class hierarchy. The following code provides the loop's framework:

do {
// perform steps 6-9
} while ((pClass = pClass->myParent()) != NULL);

Get a pointer to the OPM protocol extension for the AcRxClass:

OPMPropertyExtension* pExtension = NULL;
pExtension = 
GET_OPMEXTENSION_CREATE_PROTOCOL()
    ->CreateOPMObjectProtocol(pClass);

Use the pointer returned in step 5 to get the property manager:

IPropertyManager* pManager = NULL;
pManager = pExtension->GetPropertyManager();

Cast the property manager pointer to IUnknown*:

VARIANT vUnk = CComVariant(static_cast<IUnknown*>(pManager);

Add the property manager's IUnknown pointer to the array:

PropMgrArray.PutElement(&n, &vUnk);
n++;

You should apply a process similar to steps 6–9 to get per-instance property sources, as shown in the following pseudo-code:

COleSafeArray PropSrcArray;
VARIANT vUnk;
OPMPerInstancePropertyExt* pPiPex = NULL;
pPiPex = GET_OPM_PERINSTANCE_CREATE_PROTOCOL()->
CreateOPMPerInstancePropertyExtension(pClass->name());
VARIANT* pNames;
pPiPex->GetObjectPropertySourceNames(pNames);
IPropertySource* pPropSrc = NULL;
for (int i = 0; NULL != pNames[i]; i++) {
pPropSrc = GET_OPM_PERINSTANCE_SOURCES()->
    GetPropertySourceAt(pNames[i]);
vUnk = CComVariant(static_cast<IUnknown*>(pPropSrc);
PropSrcArray.PutElement(&n, &vUnk);
n++;
}

After you have found all property managers and property sources that apply to an object, you add their IUnknown pointers to a single SAFEARRAY. You then add this SAFEARRAY to the array that is passed as the Reset() method's second argument.