2
votes

I'm building a "plug-in" of sorts for an already-deployed VB6 executable. I'm using .NET along with COM-Interop. The VB6 creates a blank form and then loads my .NET UserControl into it (however by now the .dll has been compiled into a .ocx ActiveX UserControl that can be seen by VB6).

I've got it working well, but I would like to be able to close the VB6 parent form from inside of my .NET code. I am able to add VB6 code into my VB6-ifyed UserControl, but I cannot seem to find an event that fires when the UserControl is destroyed.

What I've tried so far:

  • Calling ParentForm.Close from the Disposing event of my .NET control. Receive error Object Reference not set to Instance of an Object.
  • Trying to close from the VB6 (I am able to get a handle on the parent form from there). Using ControlRemoved, Terminated, and a couple other hackish workarounds that truly make no sense in retrospect don't get triggered.
  • Calling Application.Exit (truly getting desperate at this point) closes the whole Application (who woulda thunk...)

I looked in the VB6 Interop code that I put in my .NET control and the following does look promising:

#Region "VB6 Events"

'This section shows some examples of exposing a UserControl's events to VB6.  Typically, you just
'1) Declare the event as you want it to be shown in VB6
'2) Raise the event in the appropriate UserControl event.

Public Shadows Event Click() 'Event must be marked as Shadows since .NET UserControls have the same name.
Public Event DblClick()

Private Sub InteropUserControl_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click
    RaiseEvent Click()
End Sub

Private Sub InteropUserControl_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick
    RaiseEvent DblClick()
End Sub

#End Region

Is it just a matter of adding an event in this section? I'm not terribly familiar with Interop, or VB6 for that matter.

1
I would think you should just raise an event from the .Net control, but I'm not very familiar with interop either, so I'm not very sure how you do it. - MarkJ

1 Answers

1
votes

Alright, I figured it out and will post what I did for future generations :P

I was right with the event handlers in the VB6 code, and MarkJ was correct as well.

I created an event in the .NET code,

Public Event KillApp()

and then when I wanted to close everything, raised it:

RaiseEvent KillApp()

In the VB6 UserControl code, I declared the event again,

Public Event KillApp()

and then added a handler for it:

Private Sub MenuCtl_KillApp()
    Unload Me.ParentForm
End Sub

where MenuCtl is my instance of the .NET control, and Me.ParentForm is the VB6 container form that houses the control. It now correctly closes the form!

In retrospect it makes a lot of sense, but I was unaware that you could pass events back and forth between managed/unmanaged that easily.