PROPVARIANT 结构 (propidl.h)
在 IPropertyStorage 的 ReadMultiple 和 WriteMultiple 方法中使用 PROPVARIANT 结构来定义属性集中的属性的类型标记和值。
PROPVARIANT 结构也由 IPropertyStore 的 GetValue 和 SetValue 方法使用,这将取代 IPropertySetStorage 作为 Windows Vista 中项目属性编程的主要方法。 有关详细信息,请参阅 属性处理程序。
有五个成员。 第一个成员(值类型标记)和最后一个成员(属性的值)非常重要。 中间三个成员保留供将来使用。
语法
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_BLOB、 VT_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_STREAM、 VT_STREAMED_OBJECT
tag_inner_PROPVARIANT.pStorage
VT_STORAGE、 VT_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_OBJECT和VT_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_I1、 VT_UI1、 VT_I2、 VT_UI2、 VT_BOOL、 VT_I4、 VT_UI4、 VT_R4、 VT_R8、 VT_ERROR、 VT_I8、 VT_UI8、 VT_CY、 VT_DATE、 VT_FILETIME、 VT_CLSID、 VT_CF、 VT_BSTR、 VT_LPSTR、 VT_LPWSTR和 VT_VARIANT。 VT_VECTOR 也可以通过 OR 操作与 VT_BSTR_BLOB结合使用,但它仅供系统使用。 |
VT_ARRAY | 0x2000 | Parray | 如果类型指示器与 OR 运算符VT_ARRAY组合,则该值是指向 SAFEARRAY 的指针。 VT_ARRAY 可以将 OR 用于以下数据类型: VT_I1、 VT_UI1、 VT_I2、 VT_UI2、 VT_I4、 VT_UI4、 VT_INT、 VT_UINT、 VT_R4、 VT_R8、 VT_BOOL、 VT_DECIMAL、 VT_ERROR、 VT_CY、 VT_DATE、 VT_BSTR、 VT_DISPATCH、 VT_UNKNOWN和 VT_VARIANT。 VT_ARRAY 不能将 OR 与 VT_VECTOR 一起使用。 |
VT_BYREF | 0x4000 | P* | 如果类型指示器由 OR 运算符与VT_BYREF组合,则该值为引用。 引用类型被解释为对数据的引用,类似于 C++ 中的引用类型 (例如,“int&”) 。
VT_BYREF可以将 OR 与以下类型一起使用: VT_I1、 VT_UI1、 VT_I2、 VT_UI2、 VT_I4、 VT_UI4、 VT_INT、 VT_UINT、 VT_R4、 VT_R8、 VT_BOOL、 VT_DECIMAL、 VT_ERROR、 VT_CY、 VT_DATE、 VT_BSTR、 VT_UNKNOWN、 VT_DISPATCH、 VT_ARRAY和 VT_VARIANT。 |
VT_VARIANT | 12 | capropvar | 后跟相应值的 DWORD 类型指示器。 VT_VARIANT 只能与 VT_VECTOR 或 VT_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) |