VB和C ++ ActiveX控件以不同的方式保存其信息,如何实现C ++ ActiveX控件来取代VB ActiveX?

时间:2012-12-20 09:57:29

标签: c++ excel vb6 activex propertybag

背景

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

我的任务

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

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

问题

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

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

问题

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

2 个答案:

答案 0 :(得分:1)

属性包保存在一个流中,就是这样。

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

答案 1 :(得分: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. 它将来到IPersistStreamInit :: Load函数,它给我一个IStream。
  2. 我读了这个流并解析为VTIUI的SAFEARRAY的VARIANT(等于BYTE数组),名为“content”。
  3. 我创建了一个名为“contentReader”的VB6 COM dll实例。
  4. 我调用contentReader->内容(内容)(将我创建的SAFEARRAY传递给它)。
  5. 现在我可以通过contentReader-> Read([in] key,[out] value)读取PropertyBag中的任何键。