PROPVARIANT 结构 (propidl.h)

IPropertyStorageReadMultipleWriteMultiple 方法中使用 PROPVARIANT 结构来定义属性集中的属性的类型标记和值。

PROPVARIANT 结构也由 IPropertyStoreGetValueSetValue 方法使用,这将取代 IPropertySetStorage 作为 Windows Vista 中项目属性编程的主要方法。 有关详细信息,请参阅 属性处理程序

有五个成员。 第一个成员(值类型标记)和最后一个成员(属性的值)非常重要。 中间三个成员保留供将来使用。

注意此结构的先前定义中的 bool 成员已重命名为 boolVal,因为某些编译器现在将 bool 识别为关键字 (keyword) 。
 
注意下面定义的 PROPVARIANT 结构包括可在版本 1 属性集序列化格式中序列化的类型。 版本 1 格式支持版本 0 格式中允许的所有类型以及一些其他类型。 添加的类型包括以下注释字段中的“版本 1”。 仅当需要版本 1 属性集时,才使用这些类型。 有关详细信息,请参阅 属性集序列化
 
PROPVARIANT 结构的定义如下:

语法

typedef struct tagPROPVARIANT {
  union {
    typedef struct {
      VARTYPE      vt;
      PROPVAR_PAD1 wReserved1;
      PROPVAR_PAD2 wReserved2;
      PROPVAR_PAD3 wReserved3;
      union {
        CHAR              cVal;
        UCHAR             bVal;
        SHORT             iVal;
        USHORT            uiVal;
        LONG              lVal;
        ULONG             ulVal;
        INT               intVal;
        UINT              uintVal;
        LARGE_INTEGER     hVal;
        ULARGE_INTEGER    uhVal;
        FLOAT             fltVal;
        DOUBLE            dblVal;
        VARIANT_BOOL      boolVal;
        VARIANT_BOOL      __OBSOLETE__VARIANT_BOOL;
        SCODE             scode;
        CY                cyVal;
        DATE              date;
        FILETIME          filetime;
        CLSID             *puuid;
        CLIPDATA          *pclipdata;
        BSTR              bstrVal;
        BSTRBLOB          bstrblobVal;
        BLOB              blob;
        LPSTR             pszVal;
        LPWSTR            pwszVal;
        IUnknown          *punkVal;
        IDispatch         *pdispVal;
        IStream           *pStream;
        IStorage          *pStorage;
        LPVERSIONEDSTREAM pVersionedStream;
        LPSAFEARRAY       parray;
        CAC               cac;
        CAUB              caub;
        CAI               cai;
        CAUI              caui;
        CAL               cal;
        CAUL              caul;
        CAH               cah;
        CAUH              cauh;
        CAFLT             caflt;
        CADBL             cadbl;
        CABOOL            cabool;
        CASCODE           cascode;
        CACY              cacy;
        CADATE            cadate;
        CAFILETIME        cafiletime;
        CACLSID           cauuid;
        CACLIPDATA        caclipdata;
        CABSTR            cabstr;
        CABSTRBLOB        cabstrblob;
        CALPSTR           calpstr;
        CALPWSTR          calpwstr;
        CAPROPVARIANT     capropvar;
        CHAR              *pcVal;
        UCHAR             *pbVal;
        SHORT             *piVal;
        USHORT            *puiVal;
        LONG              *plVal;
        ULONG             *pulVal;
        INT               *pintVal;
        UINT              *puintVal;
        FLOAT             *pfltVal;
        DOUBLE            *pdblVal;
        VARIANT_BOOL      *pboolVal;
        DECIMAL           *pdecVal;
        SCODE             *pscode;
        CY                *pcyVal;
        DATE              *pdate;
        BSTR              *pbstrVal;
        IUnknown          **ppunkVal;
        IDispatch         **ppdispVal;
        LPSAFEARRAY       *pparray;
        PROPVARIANT       *pvarVal;
      };
    } tag_inner_PROPVARIANT, PROPVARIANT, *LPPROPVARIANT;
    DECIMAL decVal;
  };
} PROPVARIANT, *LPPROPVARIANT;

成员

tag_inner_PROPVARIANT

tag_inner_PROPVARIANT.vt

值类型标记。

tag_inner_PROPVARIANT.wReserved1

留待将来使用。

tag_inner_PROPVARIANT.wReserved2

留待将来使用。

tag_inner_PROPVARIANT.wReserved3

留待将来使用。

tag_inner_PROPVARIANT.cVal

VT_I1,版本 1

tag_inner_PROPVARIANT.bVal

VT_UI1

tag_inner_PROPVARIANT.iVal

VT_I2

tag_inner_PROPVARIANT.uiVal

VT_UI2

tag_inner_PROPVARIANT.lVal

VT_I4

tag_inner_PROPVARIANT.ulVal

VT_UI4

tag_inner_PROPVARIANT.intVal

VT_INT,版本 1

tag_inner_PROPVARIANT.uintVal

VT_UINT,版本 1

tag_inner_PROPVARIANT.hVal

VT_I8

tag_inner_PROPVARIANT.uhVal

VT_UI8

tag_inner_PROPVARIANT.fltVal

VT_R4

tag_inner_PROPVARIANT.dblVal

VT_R8

tag_inner_PROPVARIANT.boolVal

VT_BOOL

tag_inner_PROPVARIANT.__OBSOLETE__VARIANT_BOOL

tag_inner_PROPVARIANT.scode

VT_ERROR

tag_inner_PROPVARIANT.cyVal

VT_CY

tag_inner_PROPVARIANT.date

VT_DATE

tag_inner_PROPVARIANT.filetime

VT_FILETIME

tag_inner_PROPVARIANT.puuid

VT_CLSID

tag_inner_PROPVARIANT.pclipdata

VT_CF

tag_inner_PROPVARIANT.bstrVal

VT_BSTR

tag_inner_PROPVARIANT.bstrblobVal

VT_BSTR_BLOB

tag_inner_PROPVARIANT.blob

VT_BLOBVT_BLOBOBJECT

tag_inner_PROPVARIANT.pszVal

VT_LPSTR

tag_inner_PROPVARIANT.pwszVal

VT_LPWSTR

tag_inner_PROPVARIANT.punkVal

VT_UNKNOWN

tag_inner_PROPVARIANT.pdispVal

VT_DISPATCH,版本 1

tag_inner_PROPVARIANT.pStream

VT_STREAMVT_STREAMED_OBJECT

tag_inner_PROPVARIANT.pStorage

VT_STORAGEVT_STORED_OBJECT

tag_inner_PROPVARIANT.pVersionedStream

VT_VERSIONED_STREAM

tag_inner_PROPVARIANT.parray

| VT_ARRAYVT_*,版本 1

tag_inner_PROPVARIANT.cac

| VT_VECTORVT_I1,版本 1

tag_inner_PROPVARIANT.caub

| VT_VECTORVT_UI1

tag_inner_PROPVARIANT.cai

| VT_VECTORVT_I2

tag_inner_PROPVARIANT.caui

| VT_VECTORVT_UI2

tag_inner_PROPVARIANT.cal

| VT_VECTORVT_I4

tag_inner_PROPVARIANT.caul

| VT_VECTORVT_UI4

tag_inner_PROPVARIANT.cah

| VT_VECTORVT_I8

tag_inner_PROPVARIANT.cauh

| VT_VECTORVT_UI8

tag_inner_PROPVARIANT.caflt

| VT_VECTORVT_R4

tag_inner_PROPVARIANT.cadbl

| VT_VECTORVT_R8

tag_inner_PROPVARIANT.cabool

| VT_VECTORVT_BOOL

tag_inner_PROPVARIANT.cascode

| VT_VECTORVT_ERROR

tag_inner_PROPVARIANT.cacy

| VT_VECTORVT_CY

tag_inner_PROPVARIANT.cadate

| VT_VECTORVT_DATE

tag_inner_PROPVARIANT.cafiletime

| VT_VECTORVT_FILETIME

tag_inner_PROPVARIANT.cauuid

| VT_VECTORVT_CLSID

tag_inner_PROPVARIANT.caclipdata

| VT_VECTORVT_CF

tag_inner_PROPVARIANT.cabstr

| VT_VECTORVT_BSTR

tag_inner_PROPVARIANT.cabstrblob

| VT_VECTORVT_BSTR

tag_inner_PROPVARIANT.calpstr

| VT_VECTORVT_LPSTR

tag_inner_PROPVARIANT.calpwstr

| VT_VECTORVT_LPWSTR

tag_inner_PROPVARIANT.capropvar

| VT_VECTORVT_VARIANT

tag_inner_PROPVARIANT.pcVal

| VT_BYREFVT_I1,版本 1

tag_inner_PROPVARIANT.pbVal

| VT_BYREFVT_UI1版本 1

tag_inner_PROPVARIANT.piVal

| VT_BYREFVT_I2,版本 1

tag_inner_PROPVARIANT.puiVal

| VT_BYREFVT_UI2,版本 1

tag_inner_PROPVARIANT.plVal

| VT_BYREFVT_I4版本 1

tag_inner_PROPVARIANT.pulVal

| VT_BYREFVT_UI4,版本 1

tag_inner_PROPVARIANT.pintVal

| VT_BYREFVT_INT版本 1

tag_inner_PROPVARIANT.puintVal

| VT_BYREFVT_UINT,版本 1

tag_inner_PROPVARIANT.pfltVal

| VT_BYREFVT_R4,版本 1

tag_inner_PROPVARIANT.pdblVal

| VT_BYREFVT_R8版本 1

tag_inner_PROPVARIANT.pboolVal

| VT_BYREFVT_R8版本 1

tag_inner_PROPVARIANT.pdecVal

| VT_BYREFVT_DECIMAL版本 1

tag_inner_PROPVARIANT.pscode

| VT_BYREFVT_ERROR,版本 1

tag_inner_PROPVARIANT.pcyVal

| VT_BYREFVT_CY版本 1

tag_inner_PROPVARIANT.pdate

| VT_BYREFVT_DATE,版本 1

tag_inner_PROPVARIANT.pbstrVal

| VT_BYREFVT_BSTR,版本 1

tag_inner_PROPVARIANT.ppunkVal

| VT_BYREFVT_UNKNOWN版本 1

tag_inner_PROPVARIANT.ppdispVal

| VT_BYREFVT_DISPATCH,版本 1

tag_inner_PROPVARIANT.pparray

| VT_BYREFVT_DISPATCH,版本 1

tag_inner_PROPVARIANT.pvarVal

| VT_BYREFVT_VARIANT版本 1

decVal

| VT_BYREFVT_DECIMAL版本 1

注解

PROPVARIANT 结构还可以保存值VT_DECIMAL

    DECIMAL       decVal;        //VT_DECIMAL

但是, DECIMAL 结构的值需要特殊处理。 DECIMAL 结构的大小与整个 PROPVARIANT 结构的大小相同,并且不适合包含所有其他类型的值的联合。 相反, DECIMAL 结构的值会占用整个 PROPVARIANT 结构,包括保留字段和 vt 成员。 但是,不使用 DECIMAL 结构的第一个成员,大小与 PROPVARIANT 结构的 vt 成员相同。 因此,Win32 的 Propidl.h 头文件中的 PROPVARIANT 结构声明以与 PROPVARIANT 结构的开头相对应的方式定义 decVal 成员。 因此,若要将 DECIMAL 结构的值放入 PROPVARIANT 结构中,必须将该值加载到 decVal 成员中,并且 vt 成员设置为 VT_DECIMAL,就像任何其他值一样。

PROPVARIANT 是通过 IPropertyStorage 接口读取和写入属性值的基本数据类型。

数据类型 PROPVARIANT 与数据类型 VARIANT 相关,该类型在 OLE2 中定义为自动化的一部分。 自动化中重复使用了几个定义,如下所示:

typedef struct  tagCY {
    unsigned long      Lo;
    long               Hi;
    } CY;
 
typedef struct  tagDEC {
    USHORT             wReserved;
    BYTE               scale;
    BYTE               sign;
    ULONG              Hi32;
    ULONGLONG          Lo64;
    } DECIMAL;
 
typedef struct  tagSAFEARRAYBOUND {
    ULONG              cElements;
    LONG               lLbound;
    } SAFEARRAYBOUND;
 
typedef struct  tagSAFEARRAY {
    USHORT             cDims;
    USHORT             fFeatures;
    ULONG              cbElements;
    ULONG              cLocks;
    PVOID              pvData;
    SAFEARRAYBOUND     rgsabound [ * ];
    } SAFEARRAY;
 
typedef CY             CURRENCY;
typedef short          VARIANT_BOOL;
typedef unsigned short VARTYPE;
typedef double         DATE;
typedef OLECHAR*       BSTR;

此外,某些类型对 PROPVARIANT 结构是唯一的:

typedef struct  tagCLIPDATA {
    // cbSize is the size of the buffer pointed to 
    // by pClipData, plus sizeof(ulClipFmt)
    ULONG              cbSize;
    long               ulClipFmt;
    BYTE*              pClipData;
    } CLIPDATA;

在唯一 的 PROPVARIANT 类型中,有几种数据类型定义其他数据类型的计数数组。 所有计数数组的数据类型都以字母 CA(例如 CAUB)开头,具有 OR 运算符 vt 值 (元素的 VarType 和具有 VT_VECTOR) 的 OR 运算符。 计数数组结构具有以下形式 (其中 name 是计数数组) 的特定名称。

#define TYPEDEF_CA(type, name) 
 
    typedef struct tag ## name {\
        ULONG cElems;\
        type *pElems;\
        } name
Propvariant 类型 代码 Propvariant 成员 值表示形式
VT_EMPTY 0 类型指示器为 VT_EMPTY 的属性没有与之关联的数据;也就是说,值的大小为零。
VT_NULL 1 这类似于指向 NULL 的指针。
VT_I1 16 cVal 1 字节带符号整数。
VT_UI1 17 bVal 1 字节无符号整数。
VT_I2 2 iVal 表示 2 字节带符号整数值的两个字节。
VT_UI2 18 uiVal 2 字节无符号整数。
VT_I4 3 lVal 4 字节有符号整数值。
VT_UI4 19 ulVal 4 字节无符号整数。
VT_INT 22 intVal 4 字节带符号整数值 (等效 于 VT_I4) 。
VT_UINT 23 uintVal 4 字节无符号整数 (等效 于 VT_UI4) 。
VT_I8 20 hVal 8 字节有符号整数。
VT_UI8 21 uhVal 8 字节无符号整数。
VT_R4 4 fltVal 32 位 IEEE 浮点值。
VT_R8 5 dblVal 64 位 IEEE 浮点值。
VT_BOOL 11 boolVal 在早期设计中 (bool) 布尔值,包含 0 (FALSE) 或 -1 的 WORD (TRUE) 。
VT_ERROR 10 scode 包含状态代码的 DWORD
VT_CY 6 cyVal 8 字节二的补整数 (按 10,000) 缩放。 此类型通常用于货币金额。
VT_DATE 7 date 一个 64 位浮点数,表示自 1899 年 12 月 31 日以来) 的天数 (而不是秒数。 例如,1900 年 1 月 1 日为 2.0,1900 年 1 月 2 日为 3.0,依此) 。 这与 VT_R8 存储在相同的表示形式中。
VT_FILETIME 64 filetime Win32 定义的 64 位 FILETIME 结构。 建议将所有时间都存储在世界坐标时间 (UTC) 中。
VT_CLSID 72 puuid 指向类标识符的指针 (CLSID) (或其他全局唯一标识符 (GUID) ) 。
VT_CF 71 pclipdata 指向 CLIPDATA 结构的指针,如上所述。
VT_BSTR 8 bstrVal 指向以 null 结尾的 Unicode 字符串的指针。 字符串前面紧接一个表示字节计数的 DWORD ,但 bstrVal 将超过此 DWORD 指向字符串的第一个字符。 必须使用 Automation SysAllocString 和 SysFreeString 调用来分配和释放 BSTR
VT_BSTR_BLOB 0xfff bstrblobVal 仅供系统使用。
VT_BLOB 65 blob DWORD 字节计数,后跟该多个字节的数据。 字节计数不包括计数本身长度的四个字节;空 Blob 成员的计数为零,后跟零个字节。 这类似于 VT_BSTR 值,但不保证数据末尾有 null 字节。
VT_BLOBOBJECT 70 blob 一个 blob 成员,该成员包含一个序列化对象,其表示形式与 VT_STREAMED_OBJECT中显示的表示形式相同。 也就是说, DWORD 字节计数 (,其中字节计数不包括自身的大小) 采用类标识符的格式,后跟该类的初始化数据。

VT_BLOB_OBJECTVT_STREAMED_OBJECT之间的唯一显著区别是前者没有后者会有的系统级存储开销,因此更适合涉及小对象数的方案。

VT_LPSTR 30 pszVal 指向系统默认代码页中以 null 结尾的 ANSI 字符串的指针。
VT_LPWSTR 31 pwszVal 指向用户默认区域设置中以 null 结尾的 Unicode 字符串的指针。
VT_UNKNOWN 13 punkVal 新建。
VT_DISPATCH 9 pdispVal 新建。
VT_STREAM 66 pStream 指向 IStream 接口的指针,该接口表示与“内容”流同级流的流。
VT_STREAMED_OBJECT 68 pStream VT_STREAM,但指示流包含序列化对象,该对象是 CLSID,后跟类的初始化数据。 该流是包含属性集的“Contents”流的同级流。
VT_STORAGE 67 pStorage 指向 IStorage 接口的指针,表示与“内容”流的同级存储对象。
VT_STORED_OBJECT 69 pStorage VT_STORAGE,但指示指定的 IStorage 包含可加载对象。
VT_VERSIONED_STREAM 73 pVersionedStream 具有 GUID 版本的流。
VT_DECIMAL 14 decVal DECIMAL 结构。
VT_VECTOR 0x1000 约* 如果使用 OR 运算符将类型指示器与VT_VECTOR组合在一起,则该值是计数数组值之一。 这会创建元素的 DWORD 计数,后跟指向值的指定重复的指针。

例如, VT_LPSTR|VT_VECTOR 的类型指示器具有 DWORD 元素计数,后跟指向 LPSTR 元素数组的指针。

VT_VECTOR 可由 OR 运算符组合为以下类型: VT_I1VT_UI1VT_I2VT_UI2VT_BOOLVT_I4VT_UI4VT_R4VT_R8VT_ERRORVT_I8VT_UI8VT_CYVT_DATEVT_FILETIMEVT_CLSIDVT_CFVT_BSTRVT_LPSTRVT_LPWSTRVT_VARIANTVT_VECTOR 也可以通过 OR 操作与 VT_BSTR_BLOB结合使用,但它仅供系统使用。

VT_ARRAY 0x2000 Parray 如果类型指示器与 OR 运算符VT_ARRAY组合,则该值是指向 SAFEARRAY 的指针。 VT_ARRAY 可以将 OR 用于以下数据类型: VT_I1VT_UI1VT_I2VT_UI2VT_I4VT_UI4VT_INTVT_UINTVT_R4VT_R8VT_BOOLVT_DECIMALVT_ERRORVT_CYVT_DATEVT_BSTRVT_DISPATCHVT_UNKNOWNVT_VARIANTVT_ARRAY 不能将 ORVT_VECTOR 一起使用。
VT_BYREF 0x4000 P* 如果类型指示器由 OR 运算符与VT_BYREF组合,则该值为引用。 引用类型被解释为对数据的引用,类似于 C++ 中的引用类型 (例如,“int&”) 。

VT_BYREF可以将 OR 与以下类型一起使用: VT_I1VT_UI1VT_I2VT_UI2VT_I4VT_UI4VT_INTVT_UINTVT_R4VT_R8VT_BOOLVT_DECIMALVT_ERRORVT_CYVT_DATEVT_BSTRVT_UNKNOWNVT_DISPATCHVT_ARRAYVT_VARIANT

VT_VARIANT 12 capropvar 后跟相应值的 DWORD 类型指示器。 VT_VARIANT 只能与 VT_VECTORVT_BYREF 一起使用。
VT_TYPEMASK 0xFFF   用作 VT_VECTOR 和其他修饰符的掩码,以提取原始 VT 值。
 

使用标记VT_CF存储的剪贴板格式标识符使用五种表示形式之一,这些表示形式在 CLIPDATA 结构的 ulClipFmt 成员中使用指向特定数据类型的 pClipData 指针标识。

ulClipFmt pClipData
-1L 包含内置 Windows 剪贴板格式值的 DWORD
-2L 包含 Macintosh 剪贴板格式值的 DWORD
-3L 包含 FMTID) (格式标识符的 GUID。 这很少使用。
任何正值 一个以 null 结尾的字符串,包含 Windows 剪贴板格式名称,适合传递给 RegisterClipboardFormat 函数。 此函数注册新的剪贴板格式。 如果已存在具有指定名称的已注册格式,则不会注册新格式,并且返回值标识现有格式。 这使多个应用程序能够使用相同的注册剪贴板格式复制和粘贴数据。 格式名称比较不区分大小写,由0xC000到0xFFFF范围内的值标识。 用于字符串中字符的代码页根据代码页指示器。 此处的“正值”是字符串长度,包括末尾的 null 字节。 当寄存器剪贴板格式放置在剪贴板上或从剪贴板中检索时,它们必须采用 HGLOBAL 数据类型值的形式,后者为对象提供句柄。
0L ) (很少使用任何数据。
 

如果 ulClipFmt 成员的值为 -1,则数据采用内置 Windows 格式。 在这种情况下,pClipData 指向的缓冲区的第一个 DWORD 是剪贴板格式标识符,例如CF_METAFILEPICT。 对于CF_METAFILEPCT,以下是 METAFILEPICT 结构的变体, (它使用 WORD,而不是 DWORD 数据类型) 。 也就是说,此数据采用以下形式:

struct PACKEDMETA
{
    WORD mm;
    WORD xExt;
    WORD yExt
    WORD reserved;
};

METAFILEPICT 结构之后是元文件数据,适合传递给 SetMetaFileBitsEx 函数。 此函数根据提供的数据创建基于内存的 Windows 格式图元文件。 提供此函数是为了与 16 位版本的 Windows 兼容。 基于 Win32 的应用程序应使用 SetEnhMetaFileBits 函数。 此函数检索指定的增强格式图元文件的内容,并将其复制到缓冲区中。 如果函数成功且缓冲区指针为 NULL,则返回值是增强型图元文件的大小(以字节为单位)。 如果函数成功,并且缓冲区指针是有效的指针,则返回值是复制到缓冲区的字节数。 如果函数失败,则返回值为零。

当寄存器剪贴板格式放置在剪贴板上或从剪贴板中检索时,它们必须采用 HGLOBAL 值的形式。

要求

要求
最低受支持的客户端 Windows 2000 专业版 [桌面应用 |UWP 应用]
最低受支持的服务器 Windows 2000 Server [桌面应用 |UWP 应用]
标头 propidl.h (包括 Propidl.h)