Every property consists of a property identifier (unique within its property set), a variant type (VT or VarType) tag that represents the type of a value, and the value itself. The variant type tag describes the representation of the data in the value. In addition, a property may also be assigned a string name that can be used to identify the property, rather than using the required numerical property identifier (ID). To create and manage properties, COM defines the IPropertyStorage interface.
The IPropertyStorage interface includes methods to read and write arrays of either properties or property names. The interface includes Commit and Revert methods that are similar to IStorage methods of the same name. There are utility methods that allow you to set the class identifier (CLSID) of the property set, set the times associated with the set, and get statistics about the property set. Finally, the Enum method creates an enumerator and returns a pointer to its IEnumSTATPROPSTG interface. You can call the methods of this interface to enumerate STATPROPSTG structures on your object, which will provide information about all of the properties in the current property set.
The following is an example of how properties are represented. If a specific property in a property set holds an animal's scientific name, that name could be stored as a zero-terminated string. Stored along with the name would be a type indicator to indicate that the value is a zero-terminated string. These properties might have the following characteristics:
|Property ID||String identifier||Type indicator||Value represented|
|02||PID_ANIMALNAME||VT_LPWSTR||Zero-terminated Unicode string|
Any application that recognizes the property set format—identifying it through its format identifier (FMTID)—can look at the property with an identifier of PID_ANIMALNAME, determine that it is a zero-terminated string, and read and write the value. Although the application can call IPropertyStorage::ReadMultiple to read any or all of a property set (having first obtained a pointer), the application must know how to interpret the property set.
A property value is passed through property interfaces as an instance of the type PROPVARIANT.
It is important to distinguish between these stored (persistent) properties, and run-time properties. Variant-type value constants have names beginning with VT_. The set of valid PROPVARIANTs is, however, not entirely equivalent to the set of VARIANTs used in Automation and ActiveX controls.
The only difference between the two structures is the allowable set of VT_ (Variant Type / VarType) tags in each. Where a certain property type can be used in both a VARIANT and a PROPVARIANT, the type tag (the VT_ value) always has an identical value. Further, for a given VT_ value, the in-memory representation used in VARIANTs and PROPVARIANTs is identical. Taken all together, this approach allows the type system to catch disallowed type tags, while at the same time allowing a knowledgeable client to implement a pointer cast when appropriate.
For more information, see the following section, Property Storage Considerations.