Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass VB6 object to .NET object via interop?

I have a VB6 app that shows a .NET DLL form via interop.

I would like an event in the .NET DLL to cause a form in the VB6 app to be shown.

My idea is to have the VB6 app pass a reference to a form to the .NET DLL. Eg:

[VB6]
Dim objNetDllObject As New NetDllObject
objNetDllObject.PassVb6Form(MyForm)
objNetDllObject.ShowForm

[C#]
object Vb6Form; 
private void PassVb6Form(object form) { Vb6Form = form; }
private void button1_Click(object sender, EventArgs e) { Vb6Form.Show(); }

Will this work?

I've read elsewhere that sending objects across a 'process boundary' can cause problems. Is this correct?

like image 972
CJ7 Avatar asked Oct 10 '22 04:10

CJ7


1 Answers

One route would be to define a COM Interface in .NET:

<System.Runtime.InteropServices.GuidAttribute("0896D946-8A8B-4E7D-9D0D-BB29A52B5D08"), _
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface IEventHandler
    Sub OnEvent(ByRef sender As Object, ByRef e As Object)
End Interface

Implement this interface in VB6

Implements MyInterop.IEventHandler

Private Sub IEventHandler_OnEvent(ByRef sender As Variant, ByRef e As Variant)
    Dim id
    id = e.Entity.Id
    ' As long as e is COM Visible (not necessarily COM registered, this will work)
End Sub

and then have a Registrar in .NET with a static collection of IEventHandlers:

<ComClass(ComRegistrar.ClassId, ComRegistrar.InterfaceId, ComRegistrar.EventsId>
Public Class ComRegistrar

   Private Shared ReadOnly _eventHandlers As New Dictionary(Of String, List(Of IEventHandler))


   ' This is called by .NET code to fire events to VB6
   Public Shared Sub FireEvent(ByVal eventName As String, ByVal sender As Object, ByVal e As Object)
        For Each eventHandler In _eventHandlers(eventName)
                eventHandler.OnEvent(sender, e)
        Next
   End Sub

   Public Sub RegisterHandler(ByVal eventName As String, ByVal handler As IEventHandler)
        Dim handlers as List(Of IEventHandler)
        If Not _eventHandlers.TryGetValue(eventName, handlers)
             handlers = New List(Of IEventHandler)
             _eventHandlers(eventName) = handlers
        End If
        handlers.Add(handler)
   End Sub

End Class

Your .NET code would call FireEvent and if VB6 had previously called RegisterHandler, your VB6 IEventHandler would get called.

like image 151
Jeff Avatar answered Oct 13 '22 09:10

Jeff