# Managing Properties

Every property consists of a property identifier (unique within its property set), a type tag that represents the type of a value, and the value itself. The 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. To create and manage properties, OLE defines the IPropertyStorage interface.

The IPropertyStorage interface includes methods to read and write arrays of either properties themselves or just 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 CLSID of the property 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.

To illustrate 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
03 | PID_LEGCOUNT | VT_I2 | WORD

Any application that recognizes the property set format (identifying it through its FMTID) can look at the property with an identifier of PID_ANIMALNAME, determine it is a zero-terminated string, and read and write the value. While 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. Value type constants have names beginning with VT_. The set of valid PROPVARIANTs is, however, not completely equivalent with the set of VARIANTs used in Automation and ActiveX Controls.

The only difference between the two structures is the allowable set of VT_ 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 both 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 simply to do a pointer-cast when appropriate.