如何从.NET互操作的用户控件中关闭VB6父窗体?

3
我正在为已部署的VB6可执行文件构建一种“插件”。我正在使用.NET与COM-Interop。VB6创建一个空白表单,然后将我的.NET UserControl加载到其中(但现在.dll已编译成了.ocx ActiveX UserControl,可以被VB6看到)。
我已经使其正常工作,但我想能够从我的.NET代码中关闭VB6父窗体。我可以在VB6-ifyed UserControl中添加VB6代码,但似乎找不到当UserControl被销毁时触发的事件。
我尝试过的方法:
- 在我的.NET控件的Disposing事件中调用ParentForm.Close。收到错误“对象引用未设置为对象的实例”。 - 尝试从VB6中关闭(我能够从那里获取父窗体的句柄)。使用ControlRemoved、Terminated和一些其他奇怪的解决方法,回头看真的没有任何意义。 - 调用Application.Exit(此时真的绝望了)会关闭整个应用程序(谁能想到...)
我查看了我放在我的.NET控件中的VB6 Interop代码,以下内容看起来很有前途:
#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

这只是在这个部分中添加事件的问题吗?我对Interop或VB6并不十分了解。


我认为你应该从 .Net 控件中引发一个事件,但我对互操作也不是很熟悉,所以我不太确定该如何做。 - MarkJ
1个回答

2

好的,我找到了解决方法并会将我的做法记录下来以方便后人 :P

在VB6代码中,我的事件处理程序是正确的,MarkJ也是对的。

我在.NET代码中创建一个事件:

Public Event KillApp()

然后当我想要关闭所有内容时,我引发它:

RaiseEvent KillApp()

在VB6 UserControl代码中,我再次声明了该事件:

Public Event KillApp()

然后为其添加了一个处理程序:

Private Sub MenuCtl_KillApp()
    Unload Me.ParentForm
End Sub

这里,MenuCtl代表我使用的.NET控件实例,而Me.ParentForm是包含该控件的VB6容器表单。现在,它正确地关闭了该表单!

回顾起来,这很有道理,但我不知道你可以如此轻松地在托管/非托管代码之间传递事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接