Fire New EventException thrown: 'System.Reflection.TargetException' in mscorlib.dllAn unhandled exception of type 'System.Reflection.TargetException' occurred in mscorlib.dllAdditional information: Object does not match target type.
Fire New EventException thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dllAn unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dllAdditional information: Exception has been thrown by the target of an invocation.
Hi Andrew,
1. The class that worked for me looks like this:
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace XLServer
{
// Step 1: Defines an event sink interface (MessageEvents) to be implemented by the COM sink.
[ComVisible(true)]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface MessageEvents
{
void NewMessage(string s);
}
// Step 2: Connects the event sink interface to a class by passing the namespace and event sink interface
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComSourceInterfaces(typeof(MessageEvents))]
public class MessageHandler
{
public delegate void NewMessageDelegate(string s);
public event NewMessageDelegate NewMessage;
public MessageHandler() { }
public void FireNewMessageEvent(string s)
{
Debug.Print($"New Message {s}");
if (NewMessage != null)
{
Debug.Print($"Invoke {s}");
NewMessage.Invoke(s);
}
}
}
}
2. This is the AutoOpen:
using System.Runtime.InteropServices;
using ExcelDna.Integration;
namespace ComServer
{
[ComVisible(false)]
public class ExcelAddin : IExcelAddIn
{
public void AutoOpen()
{
ExcelDna.ComInterop.ComServer.DllRegisterServer();
}
public void AutoClose()
{
ExcelDna.ComInterop.ComServer.DllUnregisterServer();
}
}
}
3. You need to run: "TlbExp ComServer.dll" (or whatever your .dll is).
4. On the VBA side you need to make a new workbook, Alt+F11 and then Tools->Reference and browse to the ComServer.tlb.
5. Then add a Class Module, called MessageListener:
Public WithEvents mh As MessageHandler
Public status As String
Private Sub Class_Initialize()
Set mh = New MessageHandler
status = "Initialized"
End Sub
' Events and methods are matched by name and signature.
Private Sub mh_NewMessage(ByVal s As String)
MsgBox "Message " + s
End Sub
Public Sub Fire()
mh.FireNewMessageEvent "Hello there!"
End Sub
6. And this in a Module:
Sub Test()
Dim ml As New MessageListener
ml.Fire
End Sub
7. Run the Test() macro. It works fine on my machine.
-Govert