Type Indicators

After the table of Property ID/Offset Pairs comes the actual properties. Each property is stored as a DWORD type followed by the data value.

Type indicators and their associated values are defined in the OLE header files that are shipped with the Win32 SDK.

All Type/Value pairs must begin on a 32-bit boundary. Thus values may be followed with null bytes to align the subsequent pair on a 32-bit boundary. Given a count of bytes, the following code will calculate how many bytes are needed to align on a 32-bit boundary:

cbAdd = (((cbCurrent + 3) >> 2) << 2) - cbCurrent ;

Within a vector of values, each repetition of value must align with its natural alignment rather than with a 32-bit alignment. In practice, this is only significant for types VT_I2 and VT_BOOL (which have two-byte natural alignment). All other types have four-byte natural alignment. Therefore, a property value with type indicator VT_I2 | VT_VECTOR would be:

  • A DWORD element count, followed by

  • A sequence of packed two-byte integers with no padding between them.

A property value of type identifier VT_LPSTR | VT_VECTOR would be:

  • A DWORD element count (DWORD cch), followed by

  • A sequence of strings (char rgch[]), each of which may be followed by null padding to round to a 32-bit boundary.

The following table lists the standard OLE-defined property type indicators and their meaning:

Type Indicator
Code
Value Representation
VT_EMPTY
0
None. A property set with a type indicator of VT_EMPTY has no data associated with it; that is, the size of the value is zero.
VT_NULL

None. This is like a pointer to NULL.
VT_I2

Two bytes representing a 2-byte signed int value. This value will be zero-padded to a 32-bit boundary.
VT_I4

Four bytes representing a 4-byte signed int value.
VT_R4

Four bytes representing a 32-bit IEEE floating point value.
VT_R8

Eight bytes representing a 64-bit IEEE floating point value.
VT_CY

Eight-byte two's complement integer (scaled by 10,000). This type is commonly used for currency amounts.
VT_DATE

Time format used by many applications, it is a 64-bit floating point number representing days since December 31, 1899. This is stored in the same representation as VT_R8. For example, January 1, 1900 is 2.0, while January 2, 1900 is 3.0, and so on.
VT_BSTR

Counted, zero-terminated binary string; represented as a DWORD byte count (including the terminating null character) followed by the bytes of data.
VT_BOOL
11
Two bytes representing a Boolean (WORD) value containing 0 (FALSE) or -1 (TRUE). This type must be zero-padded to a 32-bit boundary.
VT_VARIANT
12
Four-byte indicator followed by the corresponding value. This is only used in conjunction with VT_VECTOR.
VT_I8
20
Eight bytes representing a signed integer.
VT_LPSTR
30
Same as VT_BSTR; this is the representation of most strings.
VT_LPWSTR
31
A counted and zero-terminated Unicode string; a DWORD character count (where the count includes the terminating null character) followed by that many Unicode (16-bit) characters. Note that the count is not a byte count, but a WORD count.
VT_FILETIME
64
64-bit FILETIME structure, as defined by Win32:
typedef struct_FILETIME{
DWORD dwLowDateTime;
DWORD dwHighDateTime;
}FILETIME;
VT_BLOB
65
DWORD count of bytes, followed by that many bytes of data. The byte count does not include the four bytes for the length of the count itself; an empty BLOB would have a count of zero, followed by zero bytes. This is similar to VT_BSTR but does not guarantee a null byte at the end of the data.
VT_STREAM
66
A VT_LPSTR (DWORD count of bytes followed by a zero-terminated string that many bytes long) that names the stream containing the data. The real value for this property is stored in a stream object, which is a sibling to the Contents stream. This type is only valid for property sets stored in the Contents stream of a storage object.
VT_STORAGE
67
A VT_LPSTR (DWORD count of bytes followed by a zero-terminated string that many bytes long) that names the storage containing the data. The real value for this property is stored in a storage object, which is a sibling to the Contents stream that contains the property set. This type is only valid for property sets stored in the Contents stream of a storage object.
VT_STREAMED_OBJECT
68
Same as VT_STREAM, but indicates that the stream object named in this property contains a serialized object, which is a CLSID followed by initialization data for the class. The named stream is a sibling to the Contents stream that contains the property set. This type is only valid for property sets stored in the Contents stream of a storage object.
VT_STORED_OBJECT
69
Same as VT_STORAGE, but indicates that the storage object named in this property contains an object. This type is only valid for property sets stored in the Contents stream of a storage object.
VT_BLOB_OBJECT
70
An array of bytes containing a serialized object in the same representation as would appear in a VT_STREAMED_OBJECT (VT_LPSTR). The only significant difference between this type and VT_STREAMED_OBJECT is that VT_BLOB_OBJECT does not have the system-level storage overhead as VT_STREAMED_OBJECT. VT_BLOB_OBJECT is more suitable for scenarios involving numerous small objects.
VT_CF
71
An array of bytes containing a Clipboard format identifier followed by the data in that format. That is, following the VT_CF identifier is the data in the format of a VT_BLOB. This is a DWORD count of bytes followed by that many bytes of data in the following format: a LONG followed by an appropriate Clipboard identifier and a property whose value is plain text should use VT_LPSTR, not VT_CF to represent the text. Notice also that an application should choose a single Clipboard format for a property's value when using VT_CF. For more information, see "Clipboard Format Identifiers," later in this appendix.
VT_CLSID
72
A CLSID, which is a DWORD, two WORDs, and eight bytes.
VT_VECTOR
0x1000
If the type indicator is one of the previous values in addition to this bit being set, then the value is a DWORD count of elements, followed by that many repetitions of the value. When VT_VECTOR is combined with VT_VARIANT (VT_VARIANT must be combined with VT_VECTOR) the value contains a DWORD element count, a DWORD type indicator, the first value, a DWORD type indicator, the second value, and so on.
Examples:
VT_LPSTR | VT_VECTOR has a DWORD element count, a DWORD byte count, the first string data, a DWORD byte count, the second string data, and so on.
VT_I2 | VT_VECTOR has a DWORD element count followed by a sequence of two-byte integers, with no padding between them.

Software for developers
Delphi Components
.Net Components
Software for Android Developers
More information resources
MegaDetailed.Net
Unix Manual Pages
Delphi Examples