Specifying Property Pages Through ISpecifyPropertyPages

An object expresses its ability to interact with one or more property pages by implementing the interface ISpecifyPropertyPages. A client can use the presence of this interface to determine whether an object supports property pages at all, enabling something like a Properties menu item or toolbar button if it does. The interface itself is quite simple, having only one specific member function:


interface ISpecifyPropertyPages : IUnknown
{
HRESULT GetPages(CAUUID *pPages);
};

The type CAUUID is a "counted array of UUIDs":


typedef struct tagCAUUID
{
ULONG cElems;
GUID *pElems;
} CAUUID;

Simply stated, the client calls ISpecifyPropertyPages::GetPages to retrieve a counted array of the CLSIDs that together describe the property pages that the object wants displayed for itself. Whereas the client allocates the CAUUID structure before calling GetPages, the object allocates and fills the actual GUID array using CoTaskMemAlloc. The object stores a pointer to this array in the pElems field of the structure and fills the cElems field with the size of the array. When the function returns, the client is responsible for the GUID array and must be sure to free it later with CoTaskMemFree.

If the client is displaying properties for a single object, it can take the GUID array and proceed to create a property frame (described in the following section). This is always the case when an object is displaying its own property sheet. If a client is trying to display a sheet for multiple objects, however, it must first call ISpecifyPropertyPages::GetPages for each object and then build a separate array containing only those property page CLSIDs that are common to all the objects. This is because each object expects only its own specified pages to send changes. Obviously, you cannot have an object's page that understands dispID 102 to mean "edit control style bits" pass a new value to another object for which dispID 102 means "enabled nuclear power plant safety devices." In short, the client must display only those property pages that all objects in the selection understand, which does require standard page implementations (such as for fonts and colors). The user will expect that all changes he or she makes to a multiple selection will apply to the entire selection in a predictable way. Building a common set of page CLSIDs is how a client meets these expectations.