IPropertyStorage-Compound 文件实现

结构化存储体系结构的 COM 实现称为 复合文件。 复合文件中实现的存储对象包括 IPropertyStorage实现、管理单个永久性属性集的接口,以及 IPropertySetStorage(管理永久性属性集组的接口)。 有关 IPropertyStorage 接口的详细信息,请参阅 IPropertyStorage属性存储注意事项

若要获取指向 IPropertyStorage复合文件实现的指针,请调用 StgCreateStorageEx 创建新的复合文件对象或 StgOpenStorageEx 以打开以前创建的复合文件对象。 对于 StgCreateStorageExstgfmt 参数应设置为STGFMT_STORAGE。 对于 StgOpenStorageExstgfmt 参数应设置为STGFMT_STORAGE或STGFMT_ANY。 在这两种情况下,riid 参数应设置为IID_IPropertySetStorage。 这两个函数都提供指向 IPropertySetStorage接口对象的指针。 通过调用 CreateOpen 方法的接口,你将获得指向 IPropertyStorage 接口的指针,可用于调用其任何方法。

获取指向 IPropertySetStorage 复合文件实现的指针的替代方法是调用较旧的 StgCreateDocfileStgOpenStorage 函数, 或指定 IID_IStorage StgCreateStorageExStgOpenStorageEx 函数IID_IStorage的 riid 参数。 在任一情况下,将返回指向对象的 IStorage 接口的指针。 对于永久性属性集,请为 IPropertySetStorage 接口调用 QueryInterface,并指定接口标识符 (IID) IID_IPropertySetStorage的标头定义名称。

何时使用

使用 IPropertyStorage 管理单个属性集中的属性。 其方法支持读取、写入和删除可与属性标识符关联的属性和可选字符串名称。 其他方法支持标准提交和还原存储作。 还有一种方法可用于设置与属性存储关联的时间,另一种方法允许分配可用于将其他代码(如用户界面代码)与属性集关联的 CLSID。 调用 Enum 方法提供了指向 IEnumSTATPROPSTG复合文件实现的指针,该实现允许枚举集中的属性。

注意

如果通过调用 StgCreateDocfileStgCreateStorageExStgOpenStorageStgOpenStorageEx 在简单模式属性集存储上获取指向 IPropertyStorage 的指针, IPropertyStorage 方法遵循简单模式流的规则。 如果为使用STGM_SIMPLE标志创建或打开的文件获取了属性集存储,则属性集存储是简单的模式。 在这种情况下,并不总是可能使基础流变大,并且无法将现有属性替换为更大的属性。 有关详细信息,请参阅 IPropertySetStorage-Compound 文件实现

 

IPropertyStorage 和缓存

IPropertyStorage 的复合文件实现 缓存内存中打开的属性集以提高性能。 因此,在调用 提交Release(最后引用)方法之前,不会将对属性集的更改写入复合文件。

简单模式属性集

如果从简单模式属性集存储对象创建属性存储对象,则属性存储对象处于简单模式。 例如,如果属性集存储对象是从 StgOpenStorageEx 函数获取的,则属性集存储对象将处于简单模式,并在 grfMode 参数中设置STGM_SIMPLE标志。 请注意,“简单模式”与“简单属性集”无关。 如果通过调用 IPropertySetStorage::Create,并使用 grfFlags 参数中设置的PROPSETFLAG_NONSIMPLE标志来创建属性集,则属性集非常简单。 有关简单和非简单属性集的详细信息,请参阅 属性集的存储和流对象。

创建简单模式属性存储对象时,其使用没有限制。 打开现有的简单模式属性存储对象时,无法增长存储属性集的基础流对象。 因此,如果更改需要更大的流,则并不总是可以修改此类属性存储对象。

属性集格式

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 的复合文件实现支持以下方法:

IPropertyStorage::ReadMultiple

读取 rgpspec 数组中指定的属性,并提供 PROPVARIANT rgvar 数组中所有有效属性的值。 在 COM 复合文件实现中,引用流或存储类型的重复属性标识符会导致多次调用 IStorage::OpenStreamIStorage::OpenStorageReadMultiple 的成功或失败取决于基础存储实现共享打开作的能力。 由于在复合文件中强制STGM_SHARE_EXCLUSIVE,因此多个打开尝试将失败。 不支持从同一父存储多次打开同一存储对象。 必须指定STGM_SHARE_EXCLUSIVE标志。

此外,为了确保通过 COM 复合文件实现中的同一 IPropertyStorage 指针多次请求相同的流或存储值属性,则打开作会成功或失败,具体取决于属性是否已打开,以及基础文件系统处理流或存储的多个打开。 因此,对流或存储值属性执行 ReadMultiple作始终会导致调用 IStorage::OpenStream,或 IStorage::OpenStorage(传递访问(STGM_READWRITE等)并共享在打开或创建原始属性集时指定的标志(STGM_SHARE_EXCLUSIVE等)。

如果方法失败,则写入到 rgvar[] 的值是未定义的。 如果成功打开某些流或存储值属性,但在执行完成之前发生错误,则应在方法返回之前释放这些属性。

IPropertyStorage::WriteMultiple

写入在 rgpspec[] 数组中指定的属性,为其分配 PROPVARIANT 标记和 rgvar[] 中指定的值。 已存在的属性分配指定的 PROPVARIANT 值。 创建当前不存在的属性。

IPropertyStorage::D eleteMultiple

删除在 rgpspec[] 中指定的属性。

IPropertyStorage::ReadPropertyNames

读取与 rgpropid[] 数组中指定的属性 ID 关联的现有字符串名称。

IPropertyStorage::WritePropertyNames

rglpwstrName 数组中指定的字符串名称分配给 rgpropid 数组中指定的属性 ID。

IPropertyStorage::D eletePropertyNames

删除 rgpropid[] 数组中指定的属性的属性名称。

IPropertyStorage::SetClass

设置属性集流的 CLSID。 在复合文件实现中,在非简单属性集(可以合法包含存储或流值属性的集合)上设置 CLSID,如 IPropertySetStorage::Create中所述,还会在基础子存储上设置 CLSID,以便可以通过调用 IStorage::Stat获取它。

IPropertyStorage::Commit

对于简单和非简单属性集,请将属性集内存映像刷新到基础存储。 此外,对于非简单事务处理模式属性集,此方法对包含属性集的存储执行提交(如 IStorage::Commit)。

IPropertyStorage::Revert

对于非简单属性集,请调用基础存储的 Revert 方法,并重新打开“contents”流。 对于简单属性集,此接口始终返回S_OK。 非simple 属性集是在 IPropertySetStorage::Create 方法中使用 PROPSETFLAG_NONSIMPLE 标志创建的。 有关详细信息,请参阅 属性集 的存储和流对象。

IPropertyStorage::Enum

构造 IEnumSTATPROPSTG的实例,可以调用这些实例来枚举 STATPROPSTG 结构,这些结构提供有关集中每个属性的信息。 此实现将创建一个数组,在该数组中读取整个属性集,并在调用 IEnumSTATPROPSTG::Clone 时共享该数组。 对属性集的更改不会反映在打开的 IEnumSTATPROPSTG 实例中。 若要查看此类更改,必须构造此枚举器的新实例。

IPropertyStorage::Stat

填充 STATPROPSETSTG 结构的成员,该结构包含有关整个属性集的数据。 返回时,提供指向结构的指针。 对于非简单存储集,此实现调用 IStorage::Stat(或 IStream::Stat)从基础存储或流获取时间。 对于简单的存储集,不会保留任何时间。

IPropertyStorage::SetTimes

仅对于非简单属性集,设置基础存储支持的时间。 复合文件存储实现支持这三项:修改、访问和创建。 SetTimes 的此实现 调用基础存储的 IStorage::SetElementTimes 方法来检索这些时间。

IPropertyStorage

IStorage::SetElementTimes