Why are COM event handlers always null?

Using in this article , I installed this interface with a visible interface to define my events:

[ComVisible(true)]
[Guid("3D8EAA28-8983-44D5-83AF-2EEC4C363079")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IParserStateEvents
{
    void OnParsed();
    void OnReady();
    void OnError();
}

Events are designed to run a class that implements this interface:

[ComVisible(true)]
public interface IParserState
{
    void Initialize(VBE vbe);

    void Parse();
    void BeginParse();

    Declaration[] AllDeclarations { get; }
    Declaration[] UserDeclarations { get; }
}

Here's the implementation:

[ComVisible(true)]
[Guid(ClassId)]
[ProgId(ProgId)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComDefaultInterface(typeof(IParserState))]
[ComSourceInterfaces(typeof(IParserStateEvents))]
[EditorBrowsable(EditorBrowsableState.Always)]
public class ParserState : IParserState
{
    //...
    public event Action OnParsed;
    public event Action OnReady;
    public event Action OnError;

    private void _state_StateChanged(object sender, System.EventArgs e)
    {
        var errorHandler = OnError; // always null
        if (_state.Status == Parsing.VBA.ParserState.Error && errorHandler != null)
        {
            errorHandler.Invoke();
        }

        var parsedHandler = OnParsed; // always null
        if (_state.Status == Parsing.VBA.ParserState.Parsed && parsedHandler != null)
        {
            parsedHandler.Invoke();
        }

        var readyHandler = OnReady; // always null
        if (_state.Status == Parsing.VBA.ParserState.Ready && readyHandler != null)
        {
            readyHandler.Invoke();
        }
    }
    //...

The handler _state_StateChangedresponds to events raised from the workflow.


The COM client code is a VBA class that looks like this:

Private WithEvents state As Rubberduck.ParserState

Public Sub Initialize()
    Set state = New Rubberduck.ParserState
    state.Initialize Application.vbe
    state.BeginParse
End Sub

Private Sub state_OnError()
    Debug.Print "error"
End Sub

Private Sub state_OnParsed()
    Debug.Print "parsed"
End Sub

Private Sub state_OnReady()
    Debug.Print "ready"
End Sub

So far, everything looks right from the Object Browser:

object browser looks right

... when the VBA code calls BeginParse, breakpoints fall into C # code, but all the handlers null, so the VBA handlers do not start:

all handlers are null in the C # code

What am I doing wrong?

+4
source share
1 answer

COM/VBA , COM COM- .

Rubberduck.ParserState, STA. VBA WithEvents , COM-. , COM- COM , .

, (#) (VBA) , ( , ). ++ ( , , , ), , VBA .NET COM interop, , , , , . , ! , , , .

, , , , , , VBA. null, , - ( ..). , COM, , , ..). , , .

: # XLS, , (Subversion/Trac).

Initialize:

public void Initialize()
{
    if (OnReady != null)
        OnReady();
}
Private Sub Worksheet_Activate()
    If state Is Nothing Then Set state = New ComEvents01.ParserState
    ' Initialize below will have C# raise an event we'd receive state_OnReady
    state.Initialize
End Sub

Private Sub state_OnReady()
    ' We do reach here from Initialize and Worksheet_Activate
End Sub
+2

All Articles