我试图将IPropertySetStorage添加到现有的IStorage文件中。我计划编写的属性及其值将根据设计进行自定义(我可以存储一些int,一些字符串等)。我不尝试符合任何现有的IStorage文件类型。

该API及其文档以现有文件格式为目标。这是习惯,因此(到目前为止)我发现的示例只是令人困惑。

问题

IPropertySetStorage::Create


(参数1)我要通过什么FMTID?数据字段上的全零可以吗?我可以化妆吗?
(参数2)CLSID可以是nullptr吗?如果没有,那应该是什么?我是否需要找出父级IStorage使用的值?
(第3项)最好使用哪个propset标志?我在想,因为我要存储字符串,所以我应该使用PROPSETFLAG_DEFAULT
(参数4)IStorage句柄已打开以供读取(我正在像现有运行时的插件一样运行)。我现在最好的猜测是使用STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE。但是我一直在STG_E_INVALIDFLAG


注意,到目前为止,我还不能在IPropertySetStorage上创建新的IStorage,但是我已经成功创建了自定义IStream,并在以后的打开操作中从中读取。

任何与我的工作更相关的教程链接都将受到赞赏。

编辑请注意,我的代码是从现有应用程序调用的,用于处理现有文件。调用我的代码时,将传递文件的根IStorage。这是我所有基于IStorage的代码。

rootStg->OpenStorage(name, nullptr, STGM_READ | STGM_SHARE_EXCLUSIVE, nullptr, 0, &spIStg);
spIStg->QueryInterface(IID_IPropertySetStorage, reinterpret_cast<void**>(&pPropSetStg));

pPropSetStg->Create(
  ::FMTID_UserDefinedProperties,
  nullptr,
  PROPSETFLAG_DEFAULT,
  STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE ,
  &pPropStg);


正如我在#4中指出的那样,它返回STG_E_INVALIDFLAG

最佳答案

(特别感谢@Xearinox)

在粘贴所有相关代码时,我注意到我正在以READ模式打开存储(我首先创建一个子存储来容纳我的零件),而不是RW(创建时为RW,但已存在时不打开)。这导致创建道具集失败。

// see STGM_READWRITE (fix)
rootStg->OpenStorage(name, nullptr, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, nullptr, 0, &spIStg);
spIStg->QueryInterface(IID_IPropertySetStorage, reinterpret_cast<void**>(&pPropSetStg));

pPropSetStg->Create(
  ::FMTID_UserDefinedProperties,
  nullptr,
  PROPSETFLAG_DEFAULT,
  STGM_CREATE|STGM_READWRITE|STGM_DIRECT|STGM_SHARE_EXCLUSIVE ,
  &pPropStg);

关于c++ - 自定义结构化存储IPropertySetStorage,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10689929/

10-11 19:08