C# до COM-событий VB6 («объект или класс не поддерживает набор событий»), но разные - PullRequest
3 голосов
/ 13 января 2020

Мне известен 10-летний вопрос с тем же названием, что и у этого, но я дважды проверил и не ошибаюсь, используя имя делегата. Это другая проблема.

Здесь на работе у нас есть старое приложение VB6, которое мне нужно научить новым трюкам. Первое, что мне нужно было сделать - это вызвать методы из. Net COM-видимой DLL, написанной в C#. У меня это работает. Теперь мне нужно, чтобы он обрабатывал входящие события уведомления о прогрессе из той же DLL. Я задал похожий вопрос вчера, когда IDE VB6 даже не видел, что у DLL есть события, которые можно предложить. Эта проблема была решена путем правильного оформления интерфейсов и классов C#.

Сначала код C#:

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

    [ComVisible(true)]
    [Guid("16fb3de9-3ffd-4efa-ab9b-0f4117259c74")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IManagedEventsToCOM
    {
        [DispId(2)]
        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();           
        }
    }
}

Теперь моя попытка использовать его в VB6. Обратите внимание, что обработчик события _tricky_NotificationEvent был сгенерирован средой IDE путем выбора _tricky из раскрывающегося списка слева и NotificationEvent из раскрывающегося списка справа, поэтому я знаю, что это событие видно в IDE VB6.

Option Explicit

Public WithEvents _tricky As NewTricksDLL.NewTricks

Private Sub Command1_Click()
    ' The next line fails with 'Object or class does not support the set of events'
    Set _tricky = CreateObject("NewTricksDLL.NewTricks")
    ' Execution never makes to the next line
    _tricky.SendAnEvent()

End Sub

Private Sub _tricky_NotificationEvent()
    ' This handler was auto generated by the IDE
End Sub

Ответы [ 2 ]

1 голос
/ 14 января 2020

Надеюсь, что это может помочь - вот минимальный доступ к VB. net реализация ваших требований: COM-интерфейс, расходуемый VB6, одно событие, один метод.

Option Explicit On
Option Strict On

<ComClass(newTricks.ClassId, newTricks.InterfaceId, newTricks.EventsId)>
Public Class newTricks

#Region "COM GUIDs"
    ' These  GUIDs provide the COM identity for this class 
    ' and its COM interfaces. If you change them, existing 
    ' clients will no longer be able to access the class.
    Public Const ClassId As String = "386d540d-f8b8-46e1-939d-7b69dd5eff0a"
    Public Const InterfaceId As String = "78b4036e-86a0-4671-997d-da5a33bf026f"
    Public Const EventsId As String = "7b0fa5b5-b45e-4db2-9282-c06e09852161"
#End Region

    ' A creatable COM class must have a Public Sub New() 
    ' with no parameters, otherwise, the class will not be 
    ' registered in the COM registry and cannot be created 
    ' via CreateObject.
    Public Sub New()
        MyBase.New()
    End Sub

    Public Event NotificationEvent()

    Public Sub SendAnEvent()
        RaiseEvent NotificationEvent()
    End Sub
End Class

Это было создано при запуске новый проект (Windows библиотека классов), удалите из проекта автоматически созданный Class1.vb, добавьте элемент класса COM, переименовав его в NewTricks. Затем добавили объявление события, а также вложенное объявление и код; также добавлен вариант заявления. Построил проект.

Это было успешно использовано из этого кода VB6. При нажатии на кнопку «Событие сработало» было записано в ближайшее окно. Это было успешно с использованием обоих методов New и CreateObject для создания ссылки на newTricks.

Option Explicit

Private WithEvents oTricks As NewTricksDll.newTricks

Private Sub Command1_Click()

  Set oTricks = New NewTricksDll.newTricks
  'Set oTricks = CreateObject("NewTricksDll.newTricks")

  oTricks.SendAnEvent

End Sub

Private Sub oTricks_NotificationEvent()
  Debug.Print "Event fired"
End Sub

Здесь приведен соответствующий код C# для кода VB. net в преобразованном виде до https://converter.telerik.com/

using Microsoft.VisualBasic;

[ComClass(newTricks.ClassId, newTricks.InterfaceId, newTricks.EventsId)]
public class newTricks
{

    // These  GUIDs provide the COM identity for this class 
    // and its COM interfaces. If you change them, existing 
    // clients will no longer be able to access the class.
    public const string ClassId = "386d540d-f8b8-46e1-939d-7b69dd5eff0a";
    public const string InterfaceId = "78b4036e-86a0-4671-997d-da5a33bf026f";
    public const string EventsId = "7b0fa5b5-b45e-4db2-9282-c06e09852161";

    // A creatable COM class must have a Public Sub New() 
    // with no parameters, otherwise, the class will not be 
    // registered in the COM registry and cannot be created 
    // via CreateObject.
    public newTricks() : base()
    {
    }

    public event NotificationEventEventHandler NotificationEvent;

    public delegate void NotificationEventEventHandler();

    public void SendAnEvent()
    {
        NotificationEvent?.Invoke();
    }
}

Я не пробовал этот C# код.

0 голосов
/ 14 января 2020

Если вы используете CreateObject, он создает объект типа Object, как мне кажется. Вы должны создать объект просто, используя New:

Set _tricky = New NewTricksDLL.NewTricks

Поскольку вы объявили переменную как WithEvents, вы не можете просто объявить ее, используя As New NewTricksDLL.NewTricks, что, я полагаю, вы, вероятно, пытались.

...