2

背景

VB 创建了一个旧的 ActiveX 控件。我将此 ActiveX 控件添加到我的 Excel 工作簿并设置了一些属性。这些属性是在保存图书时保存的。具体来说,它们是在 VB 代码中使用 PropertyBag 保存在 UserControl_WriteProperties 函数中的。所以这些属性一直保留在工作簿中。

我的任务

我必须使用 C++ 创建一个新的 ActiveX 控件以向后兼容旧控件。我需要在我的旧 Excel 工作簿中的 ActiveX 控件中保留所有信息。因此,我将 IPersistPropertyBag 实现到我的 ActiveX 控件。

我的期望是,当我打开旧 Excel 工作簿时,必须通过 PropertyBag 正确检索所有信息。

问题

我发现我的 Excel 工作簿中保留的信息是 Stream 格式的。我可以将 IPersistStreamInit 实现到我的新 ActiveX 控件,但我不理解我的 Excel 工作簿中保留的 Stream 中的格式。因此,我无法检索保留在我的 Excel 工作簿中的信息。

我想知道为什么信息以流格式保存,即使它们是通过 VB 代码中的 Propertybag 保存的。

问题

在这种情况下,有没有办法让所有信息都保存在 ActiveX 控件中?我已经找了两天了,但我找不到方法。

4

2 回答 2

1

属性包保存到流中,仅此而已。

我希望您的 C++ 控件实现 IPersistStream,因此 Excel 正在尝试使用它。我建议您首先尝试从 C++ 控件中删除 IPersistStream、IPersistStreamInit 和 IPersistStorage,只留下 IPersistPropertyBag。

于 2012-12-20T16:56:24.817 回答
1

我通过创建一个 VB6 COM dll 来处理这个任务来完成这个任务。

Option Explicit
Dim objMyPropertyBag As PropertyBag

Public Sub Contents(a_content As Variant)
    objMyPropertyBag.Contents = a_content
End Sub

Public Function Read(key As String) As String
On Error GoTo Error_Handler
    Read = objMyPropertyBag.ReadProperty(key)
Error_Handler:
    MsgBox Err.Source & Err.Number
End Function

Private Sub Class_Initialize()
    Set objMyPropertyBag = New PropertyBag
End Sub

当我打开包含旧 ActiveX 对象的旧 Excel 工作簿时。我执行以下步骤:

  1. 它将来到给我一个 IStream 的 IPersistStreamInit::Load 函数。
  2. 我读取了这个流并解析为 VT_UI1 的 SAFEARRAY 的 VARIANT(等于 BYTE 数组),称为“内容”。
  3. 我创建了一个名为“contentReader”的 VB6 COM dll 实例。
  4. 我调用 contentReader->Contents(content) (将我创建的 SAFEARRAY 传递给它)。

现在我可以通过 contentReader->Read([in] key, [out] value) 读取 PropertyBag 中的任何键。

于 2013-01-24T04:43:33.120 回答