Finding all applicable IPropertyManager interfaces from an AutoCAD object's IUnknown pointer requires several steps, as outlined in the following procedure.
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.