【问题标题】:How can events from a C# .NET DLL be handled by a VB6 formVB6 表单如何处理来自 C# .NET DLL 的事件
【发布时间】:2020-01-14 00:53:16
【问题描述】:

在工作中,我们有一个旧的 VB6 应用程序,我需要教授新的(呃)技巧。我要做的第一件事是让它从一个用 C# 编写的 .Net COM 可见 DLL 调用方法。我有那个工作。现在我需要让它处理来自同一个 DLL 的传入进度通知事件。这是 C# 代码:

namespace NewTricksDLL
{
   [ComVisible(true)]
   [ComSourceInterfaces(typeof(IManagedEventsToCOM))]
   public class NewTricks
   {
        public delegate void NotificationEventHandler(string Message);
        public event NotificationEventHandler NotifyEvent = null;

        public string SomeMethod(string message)
        {
            return Notify(message);
        }

        private string Notify(string message)
        {
            if (NotifyEvent != null)
                NotifyEvent("Notification Event Raised.");
            return message;
        }
   }

    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    interface IManagedEventsToCOM
    {
        [DispId(1)]
        void NotifyEvent(string Message);
    }
}

这是我尝试以 VB6 形式使用它的方式

Option Explicit

Public WithEvents newTricks as NewTricksDLL.NewTricks

Private Sub Command1_Click()
    Dim response as String
    Set newTricks = New NewTricksDLL.NewTricks
    AddHandler newTricks.NotifyEvent, AddressOf NotifyEventHandler
    response = newTricks.SomeMethod("Please send an event...")

End Sub

Private Sub NotifyEventHandler()
    'Nothing
End Sub

我的问题是,当我尝试运行 VB6 表单时,我得到了Compile error: Object does not source automation events.

如果我删除 WithEvents Command1_Click Sub 确实运行并且 response 确实包含 "Please send an event..." 所以我知道该方法是通过 COM 调用的。

事件的实施我哪里出了问题?

【问题讨论】:

  • AddHandler 是 vb.net 动词,而不是 vb6。如果您尝试使用 vb6 编译此代码,您应该会收到一个编译错误“未定义子或函数”。除非你有一个名为 AddHandler 的 Sub 或 Function?
  • 每当我删除 WithEvents 时,我实际上一直在注释掉该行。我确信一旦我上面详述的问题得到解决,我就会遇到 AddHandler 的问题。
  • 我希望您的 C# 代码没有定义事件,或者它可能没有包含在 COM 接口中(我的 C# 不够强大,无法查看那里有什么问题)。这就是为什么您会收到报告的编译错误。您还应该看到,如果您使用对象查看器检查 newTricks 对象,您将不会看到作为该接口一部分的事件。解决后,删除 AddHandler 行。通过在表单代码窗口中从对象选择列表中选择 newTricks 来添加事件处理程序,然后从过程选择列表中选择事件。事件处理程序将添加到您的代码中。
  • @MarkL 奇怪的是,在 ObjectBrowser 中,甚至 SomeMethod() 都没有显示为 newTricks 的成员,即使对 SomeMethod() 的调用成功完成。
  • 这能回答你的问题吗? Subscribe to C# .net Event in VB6

标签: vb6 com-interop


【解决方案1】:

您将对象声明为 WithEvents,因此该对象应出现在 Visual Studio (VB6 IDE) 代码窗口的左侧下拉列表中。选择对象后,在您的情况下为 newTricks,右侧的下拉列表将显示可用事件。单击所需的事件,IDE 将为您生成事件处理程序,但您也可以手动输入:

Private Sub newTricks_NotifyEvent()
    ' handle your event here
End Sub

【讨论】:

  • 我从右侧下拉列表中选择了事件并生成了原型事件处理程序,但是当我使用NewCreateObject 创建NewTricksDLL.NewTricks 的实例时,我收到错误@987654326 @.
【解决方案2】:

问题原来是缺少对类和接口的适当修饰。此 C# 代码允许 VB6 IDE 查看可用事件并为事件生成处理程序模板,但尝试在 VB6 中实例化类会导致 Object or class does not support the set of events。我已针对该问题提出了一个新问题。

{
    [ComVisible(true)]
    [Guid("16fb3de9-3ffd-4efa-ab9b-0f4117259c75")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface ITransfer
    {
        string SendAnEvent();
    }

    [ComVisible(true)]
    [Guid("16fb3de9-3ffd-4efa-ab9b-0f4117259c74")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IManagedEventsToCOM
    {
        [DispId(1)]
        void NotificationEvent();

    }

    [ComVisible(true)]
    [Guid("dcf177ab-24a7-4145-b7cf-fa06e892ef21")]
    [ComSourceInterfaces(typeof(IManagedEventsToCOM))]
    [ProgId("ADUTransferCS.NewTricks")]
    public class NewTricks : ITransfer
    {
        public delegate void NotificationEventHandler();
        public event NotificationEventHandler NotifificationEvent;

        public string SendAnEvent()
        {
            if (NotifificationEvent != null)
                NotifificationEvent();           
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-05-12
    • 1970-01-01
    • 2019-03-03
    • 2020-01-14
    • 2012-03-24
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多