Implementing Per-Instance Dynamic Properties

In addition to creating dynamic properties that apply to all instances of an AcRxClass, you can also apply dynamic properties to specific objects. The following interfaces provide the means for defining per-instance dynamic properties:

These interfaces are used with the following global macros:

Applications manage per-instance dynamic properties by implementing the IPropertySource interface on one or more COM objects. Instances of these COM objects are stored in the Properties palette's protocol extension framework.

When the Properties palette queries a selected object for its properties, it passes that object's IUnknown pointer to the GetProperties() method of each IPropertySourceinstance in its framework. If a GetProperties() implementation detects a pointer to a qualified object, it generates and returns dynamic properties. These generated dynamic properties are instances of IDynamicProperty or IDynamicProperty2.

Each IPropertySource instance has a unique name that it provides through its get_Name() method. AutoCAD maps all these names in a single global instance of the OPMPerInstancePropertySources class. You can access this instance with the GET_OPM_PERINSTANCE_SOURCES() macro.

To register your property source in the global listing, you first must instantiate your property source class. When you have a pointer to its instance, call the OPMPerInstancePropertySources::SetPropertySourceAt() function, passing in your property source's name and your instance pointer. The following pseudo-code demonstrates this technique:

CMyPropSource* pPropSrc = new CMyPropSource(); // implements
                                               // IPropertySource
BSTR* pName;
hr = pPropSrc->get_Name(pName);
if SUCCEEDED(hr)
GET_OPM_PERINSTANCE_SOURCES()->SetPropertySourceAt(pName, pPropSrc);

To become available to the Properties palette, your property source must be associated with an AcRxClass object. The OPMPerInstancePropertyExtension class performs this service. Instances of OPMPerInstancePropertyExtension serve a similar purpose for per-instance properties as IPropertyManager objects do for class-wide dynamic properties: they establish the link between an AcRxClass and its dynamic data. For each AcRxClass object, you can retrieve an OPMPerInstancePropertyExtension instance with the GET_OPM_PERINSTANCE_EXTENSION_PROTOCOL() macro. Call the OPMPerInstancePropertyExtension::AddObjectPropertySourceName() method on the returned pointer to register your IPropertySource object. This mechanism is shown in the following pseudo-code:

AcRxClass* pAcrxClass = AcDbMyEnt::desc();
GET_OPM_PERINSTANCE_EXTENSION_PROTOCOL(pAcrxClass)->
AddObjectPropertySourceName(pName);

The main difference between IPropertyManager2 and IPropertySource registrations lies in what is registered. Dynamic properties themselves are registered with an IPropertyManager2 object. Once registered, these properties become available to all instances of the associated AcRxClass. Per-instance dynamic properties are not registered with any object. Instead, the IPropertySource instance is registered with an OPMPerInstancePropertyExtension instance. The IPropertySource object generates per-instance properties on request at runtime, as it deems appropriate.