PROPVARIANT 结构 (propidlbase.h)

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

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

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

注意此结构的先前定义中的布尔成员已重命名为 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

tag_inner_PROPVARIANT.bVal

tag_inner_PROPVARIANT.iVal

tag_inner_PROPVARIANT.uiVal

tag_inner_PROPVARIANT.lVal

tag_inner_PROPVARIANT.ulVal

tag_inner_PROPVARIANT.intVal

tag_inner_PROPVARIANT.uintVal

tag_inner_PROPVARIANT.hVal

tag_inner_PROPVARIANT.uhVal

tag_inner_PROPVARIANT.fltVal

tag_inner_PROPVARIANT.dblVal

tag_inner_PROPVARIANT.boolVal

tag_inner_PROPVARIANT.__OBSOLETE__VARIANT_BOOL

tag_inner_PROPVARIANT.scode

tag_inner_PROPVARIANT.cyVal

tag_inner_PROPVARIANT.date

tag_inner_PROPVARIANT.filetime

tag_inner_PROPVARIANT.puuid

tag_inner_PROPVARIANT.pclipdata

tag_inner_PROPVARIANT.bstrVal

tag_inner_PROPVARIANT.bstrblobVal

tag_inner_PROPVARIANT.blob

tag_inner_PROPVARIANT.pszVal

tag_inner_PROPVARIANT.pwszVal

tag_inner_PROPVARIANT.punkVal

tag_inner_PROPVARIANT.pdispVal

tag_inner_PROPVARIANT.pStream

tag_inner_PROPVARIANT.pStorage

tag_inner_PROPVARIANT.pVersionedStream

tag_inner_PROPVARIANT.parray

tag_inner_PROPVARIANT.cac

tag_inner_PROPVARIANT.caub

tag_inner_PROPVARIANT.cai

tag_inner_PROPVARIANT.caui

tag_inner_PROPVARIANT.cal

tag_inner_PROPVARIANT.caul

tag_inner_PROPVARIANT.cah

tag_inner_PROPVARIANT.cauh

tag_inner_PROPVARIANT.caflt

tag_inner_PROPVARIANT.cadbl

tag_inner_PROPVARIANT.cabool

tag_inner_PROPVARIANT.cascode

tag_inner_PROPVARIANT.cacy

tag_inner_PROPVARIANT.cadate

tag_inner_PROPVARIANT.cafiletime

tag_inner_PROPVARIANT.cauuid

tag_inner_PROPVARIANT.caclipdata

tag_inner_PROPVARIANT.cabstr

tag_inner_PROPVARIANT.cabstrblob

tag_inner_PROPVARIANT.calpstr

tag_inner_PROPVARIANT.calpwstr

tag_inner_PROPVARIANT.capropvar

tag_inner_PROPVARIANT.pcVal

tag_inner_PROPVARIANT.pbVal

tag_inner_PROPVARIANT.piVal

tag_inner_PROPVARIANT.puiVal

tag_inner_PROPVARIANT.plVal

tag_inner_PROPVARIANT.pulVal

tag_inner_PROPVARIANT.pintVal

tag_inner_PROPVARIANT.puintVal

tag_inner_PROPVARIANT.pfltVal

tag_inner_PROPVARIANT.pdblVal

tag_inner_PROPVARIANT.pboolVal

tag_inner_PROPVARIANT.pdecVal

tag_inner_PROPVARIANT.pscode

tag_inner_PROPVARIANT.pcyVal

tag_inner_PROPVARIANT.pdate

tag_inner_PROPVARIANT.pbstrVal

tag_inner_PROPVARIANT.ppunkVal

tag_inner_PROPVARIANT.ppdispVal

tag_inner_PROPVARIANT.pparray

tag_inner_PROPVARIANT.pvarVal

decVal

注解

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 与作为 OLE2 中自动化的一部分定义的数据类型 VARIANT 相关。 自动化中重复使用了多个定义,如下所示:

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 (TRUE) 的 WORD
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 应用]
标头 propidlbase.h (包括 Propidl.h)