VB and C++ ActiveX control persist its information in different way, how can I implement C++ ActiveX control to replace VB ActiveX?

StackOverflow https://stackoverflow.com/questions/13969479

Pregunta

Background

There was an old ActiveX control created by VB. I added this ActiveX control to my Excel workbook and set some properties. These properties were saved when the book was saved. Specifically, they were saved in UserControl_WriteProperties function using PropertyBag in VB code. So these properties persisted in the workbook until now.

My Task

I have to create a new ActiveX control using C++ to be backward compatible with the old one. I need ALL information persisted in the ActiveX control which is in my old Excel workbook. So, I implement IPersistPropertyBag to my ActiveX control.

My expectation is, when I open my old Excel workbook, all information must be retrieved correctly via PropertyBag.

Problem

I've found that the information persisted in my Excel workbook is in Stream format. I can implement IPersistStreamInit to my new ActiveX control but I don't understand the format in the Stream persisted in my Excel workbook. So, I can't retrieve the information persisted in my Excel workbook.

I wonder why the information was saved in Stream format even though they were saved via Propertybag in VB code.

Question

Is there a way to get all information persisted in the ActiveX control in this scenario? I've been finding it for two days but I can't find a way.

¿Fue útil?

Solución 2

I've done this task by creating a VB6 COM dll to handle this task.

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

When I open the my old Excel workbook which contains an old ActiveX object. I do the following steps:

  1. It will come to IPersistStreamInit::Load function which give me an IStream.
  2. I read this stream and parse to VARIANT of SAFEARRAY of VT_UI1 (equal to array of BYTE) called "content".
  3. I create an instance of VB6 COM dll, called "contentReader".
  4. I call contentReader->Contents(content) (pass the SAFEARRAY I've created to it).

Now I can read any key in the PropertyBag via contentReader->Read([in] key, [out] value).

Otros consejos

The property bag is saved into a stream, that's all.

I expect your C++ control implements IPersistStream, so Excel is trying to use that. I suggest you first try ripping out the IPersistStream, IPersistStreamInit and IPersistStorage from the C++ control, leaving only IPersistPropertyBag.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top