IPropertyStorage-Compound 文件实现
结构化存储体系结构的 COM 实现称为 复合文件。 复合文件中实现的存储对象包括 IPropertyStorage(管理单个持久属性集的接口)和 IPropertySetStorage(管理持久属性集组的接口)的实现。 有关 IPropertyStorage 接口的详细信息,请参阅 IPropertyStorage 和 属性存储注意事项。
若要获取指向 IPropertyStorage 的复合文件实现的指针,请调用 StgCreateStorageEx 创建新的复合文件对象,或 调用 StgOpenStorageEx 打开以前创建的复合文件对象。 对于 StgCreateStorageEx, stgfmt 参数应设置为 STGFMT_STORAGE。 对于 StgOpenStorageEx, stgfmt 参数应设置为 STGFMT_STORAGE 或 STGFMT_ANY。 在这两种情况下, riid 参数都应设置为 IID_IPropertySetStorage。 这两个函数都提供指向对象 IPropertySetStorage 接口的 指针。 通过调用该接口的 Create 或 Open 方法,你将获得指向 IPropertyStorage 接口的指针,该接口可用于调用其任何方法。
获取指向 IPropertySetStorage 复合文件实现的指针的另一种方法是调用较旧的 StgCreateDocfile 和 StgOpenStorage 函数,或指定 stgCreateStorageEx 或 StgOpenStorageEx 函数IID_IStorage riid 参数。 在任一情况下,都返回指向对象的 IStorage 接口的指针。 使用永久性属性集时,为 IPropertySetStorage 接口调用 QueryInterface,为接口标识符指定标头定义的名称 (IID) IID_IPropertySetStorage。
何时使用
使用 IPropertyStorage 管理单个属性集中的属性。 其方法支持读取、写入和删除属性以及可与属性标识符关联的可选字符串名称。 其他方法支持标准提交和还原存储操作。 还有一种方法可用于设置与属性存储关联的时间,另一种方法允许分配 CLSID,该 CLSID 可用于将其他代码(如用户界面代码)与属性集相关联。 调用 Enum 方法会提供指向 IEnumSTATPROPSTG 的复合文件实现的指针,这使你可以枚举集中的属性。
注意
如果通过在简单模式属性集存储上调用 StgCreateDocfile、StgCreateStorageEx、StgOpenStorage 或 StgOpenStorageEx 来获取指向 IPropertyStorage 的指针,则 IPropertyStorage 方法遵循简单模式流的规则。 如果属性集存储是为使用 STGM_SIMPLE 标志创建或打开的文件获取的,则属性集存储为简单模式。 在这种情况下,并不总是能够使基础流更大,并且不可能将现有属性替换为更大的属性。 有关详细信息,请参阅 IPropertySetStorage-Compound 文件实现。
IPropertyStorage 和缓存
IPropertyStorage 的复合文件实现将打开的属性集缓存在内存中,以提高性能。 因此,在调用 Commit 或 Release (最后一个引用) 方法之前,不会将属性集的更改写入复合文件。
简单模式属性集
如果从简单模式属性集存储对象创建属性存储对象,则属性存储对象处于简单模式。 例如,如果属性集存储对象是从 StgOpenStorageEx 函数获取的,并在 grfMode 参数中设置了 STGM_SIMPLE 标志,则该对象将处于简单模式。 请注意,“简单模式”与“简单属性集”无关。 如果在 grfFlags 参数中设置PROPSETFLAG_NONSIMPLE标志的情况下调用 IPropertySetStorage::Create 来创建属性集,则属性集很简单。 有关简单和非简单属性集的详细信息,请参阅 属性集的存储和流对象。
创建简单模式属性存储对象时,对其使用没有限制。 打开现有的简单模式属性存储对象时,无法扩展存储该属性集的基础流对象。 因此,如果更改需要更大的流,则并不总是可以修改此类属性存储对象。
属性集格式
IPropertyStorage 的复合文件实现支持版本 0 和版本 1 属性集序列化格式。 在 Windows 2000 上运行的计算机上支持版本 1 格式。 有关详细信息,请参阅 属性集序列化。 属性集以版本 0 格式创建,除非请求新功能,否则将保留该格式。 发生这种情况时,格式将更新为版本 1。
例如,如果使用 PROPSETFLAG_DEFAULT 标志创建属性集,则其格式为版本 0。 只要将符合版本 0 格式的属性类型写入该属性集并从中读取,该属性集将保持为版本 0 格式。 如果将版本 1 属性类型写入属性集,则属性集会自动更新为版本 1。 随后,仅识别版本 0 的实现无法再读取该属性集。
IPropertyStorage 和 Variant 类型
IPropertyStorage 的复合文件实现不支持 PROPVARIANT 结构的 vt 成员中VT_UNKNOWN或VT_DISPATCH的变体类型。
下表列出了 SafeArray 中支持的变体类型;也就是说,这些值可以与 PROPVARIANT 结构的 vt 成员中的VT_ARRAY组合使用。
IPropertyStorage 的复合文件实现在 SafeArray 中支持的变体类型
VT_I1
VT_UI1
VT_I2
VT_UI2
VT_I4
VT_UI4
VT_INT
VT_UINT
VT_R4
VT_R8
VT_CY
VT_DATE
VT_BSTR
VT_BOOL
VT_DECIMAL
VT_ERROR
VT_VARIANT
当VT_VARIANT与 VT_ARRAY 结合使用时,SafeArray 本身会保留 PROPVARIANT 结构。 但是,这些元素的类型必须取自前面的列表,不能VT_VARIANT,也不能包括VT_VECTOR、VT_ARRAY或VT_BYREF指示器。
IPropertyStorage 方法
IPropertyStorage 的复合文件实现支持以下方法:
-
读取 rgpspec 数组中指定的属性,并提供 PROPVARIANT 的 rgvar 数组中所有有效属性的值。 在 COM 复合文件实现中,引用流或存储类型的重复属性标识符会导致多次调用 IStorage::OpenStream 或 IStorage::OpenStorage , 而 ReadMultiple 的成功与否取决于基础存储实现共享打开操作的能力。 由于在复合文件中STGM_SHARE_EXCLUSIVE是强制的,因此多次打开尝试将失败。 不支持从同一父存储多次打开同一存储对象。 必须指定STGM_SHARE_EXCLUSIVE标志。
此外,为了确保在通过 COM 复合文件实现中的同一 IPropertyStorage 指针多次请求相同的流或存储值属性时线程安全操作,打开操作将成功或失败,具体取决于属性是否已打开,以及基础文件系统是否处理流或存储的多个打开。 因此,对流或存储值属性执行的 ReadMultiple 操作始终会导致调用 IStorage::OpenStream 或 IStorage::OpenStorage,后者传递访问 (STGM_READWRITE,依此类推) 和共享标志 (STGM_SHARE_EXCLUSIVE,) 打开或创建原始属性集时指定。
如果方法失败,则写入 rgvar[] 的值未定义。 如果某些流值或存储值属性已成功打开,但在执行完成之前发生错误,则应在方法返回之前释放这些属性。
-
写入 rgpspec[] 数组中指定的属性,并为其分配 rgvar[] 中指定的 PROPVARIANT 标记和值。 为已存在的属性分配指定的 PROPVARIANT 值。 创建当前不存在的属性。
-
删除 rgpspec[] 中指定的属性。
-
读取与 rgpropid[] 数组中指定的属性 ID 关联的现有字符串名称。
-
将 rglpwstrName 数组中指定的字符串名称分配给 rgpropid 数组中指定的属性 ID。
-
删除 rgpropid[] 数组中指定的属性的属性名称。
-
设置属性集流的 CLSID 。 在复合文件实现中,在非简单属性集上设置 CLSID (可合法包含存储或流值属性集,如 IPropertySetStorage::Create) 还会设置基础子存储上的 CLSID,以便可以通过调用 IStorage::Stat 获取它。
-
对于简单和非简单属性集,将属性集内存映像刷新到基础存储。 此外,对于非简单事务处理模式属性集,此方法对包含属性集的存储执行提交 (如 IStorage::Commit) 中所示。
-
仅对于非简单属性集,调用基础存储的 Revert 方法并重新打开“contents”流。 对于简单属性集,此接口始终返回S_OK。 非简单属性集是使用 IPropertySetStorage::Create 方法中的 PROPSETFLAG_NONSIMPLE 标志创建的属性集。 有关详细信息,请参阅 属性集的存储和流对象 。
-
构造 IEnumSTATPROPSTG 的实例,可调用其方法枚举 STATPROPSTG 结构,这些结构提供有关集中每个属性的信息。 此实现将创建一个数组,该数组将读取整个属性集,并在调用 IEnumSTATPROPSTG::Clone 时可以共享该数组。 对属性集的更改不会反映在打开的 IEnumSTATPROPSTG 实例中。 若要查看此类更改,必须构造此枚举器的新实例。
-
填充 STATPROPSETSTG 结构的成员,该结构包含有关整个属性集的数据。 返回时,提供指向 结构的指针。 对于非简单存储集,此实现调用 IStorage::Stat (或 IStream::Stat) ,以从基础存储或流获取时间。 对于简单存储集,不保留任何时间。
-
仅对于非简单属性集,设置基础存储支持的时间。 复合文件存储实现支持以下三项:修改、访问和创建。 SetTimes 的此实现调用基础存储的 IStorage::SetElementTimes 方法来检索这些时间。
相关主题