如何从 "array" 的 IDispatch 接口获取成员?

How do I get a member from an IDispatch interface which is an "array"?

我是一名 C 程序员,但我是 Windows 和 COM 编程的新手。

对于以下 C# 代码:

//Change the font of the selected text in the running PowerPoint.
Application app = Marshal.GetActiveObject("Powerpoint.Application");
app.ActiveWindow.Selection.TextRange.Font = ...;

我知道如何用 C 编写相应的 OLE 代码。简单回顾一下:

  1. 调用GetActiveObject获取应用程序的IUnknown接口;
  2. 调用IUnknown_QueryInterface获取应用的IDispatch;
  3. DISPATCH_PROPERTYGET[=调用IDispatch_GetIDsOfNamesIDispatch_Invoke 41=] 获取当前 IDispatch 的命名 属性。
  4. 重复步骤 2 到步骤 4,直到我们到达第二个最里面的 属性(即上例中的 TextRange)。
  5. DISPATCH_PROPERTYPUT[=调用IDispatch_GetIDsOfNamesIDispatch_Invoke 41=]设置最里面的值属性(即上例中的Font)。

问题来了: 如果 属性 是一个“数组”怎么办?例如,给定以下 C# 代码:

Application app = Marshal.GetActiveObject("Illustrator.Application");
foreach (object textFrame in app.ActiveDocument.TextFrames)
    ...;

上面的C#代码迭代了TextFrames“数组”中的每个文本框,我不知道在C中“迭代”这样的属性的相应C代码。我已经通过互联网搜索了微软开发参考资料,但未能得到任何线索。

如何使用 C 从“数组”属性 中获取成员?

Textframe 可能不是数组。我想这是一个枚举器。 但是在调试器中检查返回的类型。

或者您需要向我们展示您正在使用的接口的类型库或 IDL 文件。

如果它是一个迭代器,TextFrames 对象有一个 属性 _NewEnum。这有一个接口 IEnumVARIANT ...通常调用 OnNext 直到 OnNext returns S_FALSE.

所以这里发生的是 ForEach 请求调用 TextFrames 对象的 _NewEnum 属性。它可能会调用 OnReset 或 OnClose,而不是为每个成员调用 OnNext...

如果它是一个数组,您将得到一个包含 SAFEARRAY 的 VARIANT。