Handling events exposed on a .NET class via COM in VB6
My test .NET (class libary registered for interop in compiler settings) code:
Imports System.Runtime.InteropServices
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch), ComVisible(True)> _
Public Interface MyEventInterface
<DispId(1)> Event Exploded(ByVal Text As String)
<DispId(2)> Sub PushRedButton()
End Interface
<ClassInterface(ClassInterfaceType.None)> _
Public Class EventTest
Implements MyEventInterface
Public Event Exploded(ByVal Text As String) Implements MyEventInterface.Exploded
Public Sub PushRedButton() Implements MyEventInterface.PushRedButton
RaiseEvent Exploded("Bang")
End Sub
End Class
My test VB6 application winforms code (which references the above class libary):
Public ct As New ComTest1.EventTest
Private Sub Command1_Click()
ct.add_Exploded (ExplodedHandler)
ct.PushRedButton
ct.remove_Exploded (ExplodedHandler)
End Sub
Private Sub ExplodedHandler(ByVal Text As String)
MsgBox Text
End Sub
Specifially I'm not sure how to set up the handler in VB6 the compile error I get is "Argument not optional" on this line in the VB6:
ct.add_Exploded (ExplodedHandler)
C#
[ComVisible(true)] //Exposed
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] //Our managed interface will be IDispatch
public interface IMathEvents
{
void OnOperationCompleted(string message);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IMathEvents))] //Our event source is IMathEvents interface
[ComDefaultInterface(typeof(IMath))]
public class Math:IMath /*IMath interface just declares a method named Add */
{
public int Add(int x, int y)
{
if (null != this.OnOperationCompleted)
this.OnOperationCompleted("Operation completed, result: " + (x+y).ToString());
return x + y;
}
[ComVisible(false)]
public delegate void OperationCompletedDel(string message); //No need to expose this delegate
public event OperationCompletedDel OnOperationCompleted;
}
[ComVisible(true)]
public interface IMath
{
int Add(int x, int y);
}
vb
Private WithEvents m As Math
Private Sub Form_Load()
Set m = New PayClient.Math
End Sub
Private Sub m_OnOperationCompleted(ByVal Text As String)
MsgBox Text
End Sub
Private Sub Command2_Click()
m.Add 1, 2
End Sub
Use <ComSourceInterfaces(GetType(
the interface name))>
for the events in .NET and WithEvents
in VB6
.NET class libary:
Imports System.Runtime.InteropServices
' This interface is to expose the events
<Guid("28C7DCE1-90EF-4a30-AF7F-4187F9FFFDEB")> _
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface MathsEvents
<DispId(1)> _
Sub Calculated(ByVal Result As Double)
End Interface
' This interface is to expose the properties and methods
<Guid("86CE5E8D-777D-4cd5-8A7D-7F58737F1DB4")> _
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface _Maths
<DispId(2)> _
Property ValueA() As Double
<DispId(3)> _
Property ValueB() As Double
<DispId(4)> _
ReadOnly Property Result() As Double
<DispId(5)> _
Sub Add()
End Interface
' This is the actual class
' The events are exposed by using the ComSourceInterfaces attribute
' The properties and methods are exposed using the Implements keyword
<Guid("C58721B1-15B3-4eeb-9E1E-BCDA33D38EE6")> _
<ClassInterface(ClassInterfaceType.None)> _
<ComSourceInterfaces(GetType(MathsEvents))> _
Public Class Maths
Implements _Maths
Public Event Calculated(ByVal Result As Double)
Private mValueA As Double
Private mValueB As Double
Private mResult As Double
Public Property ValueA() As Double Implements _Maths.ValueA
Get
Return mValueA
End Get
Set(ByVal value As Double)
mValueA = value
End Set
End Property
Public Property ValueB() As Double Implements _Maths.ValueB
Get
Return mValueB
End Get
Set(ByVal value As Double)
mValueB = value
End Set
End Property
Public ReadOnly Property Result() As Double Implements _Maths.Result
Get
Return mResult
End Get
End Property
Public Sub New()
mValueA = 0
mValueB = 0
mResult = 0
End Sub
Public Sub Add() Implements _Maths.Add
mResult = mValueA + mValueB
RaiseEvent Calculated(mResult)
End Sub
End Class
VB6 test application:
Private WithEvents calc As Maths
Private Sub btnAdd_Click()
calc.ValueA = CDbl(txtValueA.Text)
calc.ValueB = CDbl(txtValueB.Text)
calc.Add
End Sub
Private Sub calc_Calculated(ByVal Result As Double)
txtResult.Text = CStr(Result)
End Sub
Private Sub Form_Load()
Set calc = New Maths
End Sub