-1

I'm trying to write a C#-based WPF application that uses a C++ DLL. The C# application is for the user interface and it has all advantages of WPF. The C++ DLL uses Win32 functions (for example to enumerate windows).

Now I want the C++ DLL to raise event that can be handled in the C# application. This is what I've tried (based on this article):

//cpp file

#using <System.dll>

using namespace System;

struct WIN {
    HWND Handle;
    char ClassName;
    char Title;
};

delegate void wDel(WIN);
event wDel^ wE;
void GotWindow(WIN Window) {
    wE(Window);
}

When I try to compile this code, these errors are thrown:

C3708: 'wDel': improper use of 'event'; must be a member of a compatible event source

C2059: syntax error: 'event'

C3861: 'wE': identifier not found

Community
  • 1
  • 1
Jan Böhm
  • 89
  • 1
  • 11
  • The *event* keyword must appear inside a `public ref class`. You furthermore must use managed `value struct` instead of a native `struct` to allow C# code to access the structure members. – Hans Passant Oct 27 '14 at 18:50

1 Answers1

0

Your event needs to be a member of some managed class, possibly static. e.g.:

#include "stdafx.h"
#include "windows.h"

using namespace System;

struct WIN {
    HWND Handle;
    char ClassName;
    char Title;
};

delegate void wDel(WIN);

ref class WindowEvents abstract sealed // abstract sealed ref class in c++/cli is like a static class in c#
{
    public:
        static event wDel^ wE;

        static void GotWindow(WIN Window) {
            wE(Window);
        }
};

Update

If you need to convert your unmanaged HWND to an IntPtr, since IntPtr is the standard P/Invoke signature for an HWND in c#, you might consider something like the following:

#include "stdafx.h"
#include "windows.h"

using namespace System;

#pragma managed(push,off)

struct WIN {  // Unmanaged c++ struct encapsulating the unmanaged data.
    HWND Handle;
    char ClassName;
    char Title;
};

#pragma managed(pop)

public value struct ManagedWIN  // Managed c++/CLI translation of the above.
{
public:
    IntPtr Handle; // Wrapper for an HWND
    char   ClassName;
    char   Title;
    ManagedWIN(const WIN win) : Handle(win.Handle), ClassName(win.ClassName), Title(win.Title)
    {
    }
};

public delegate void wDel(ManagedWIN);

public ref class WindowEvents abstract sealed // abstract sealed ref class in c++/cli is like a static class in c#
{
    public:
        static event wDel^ wE;

    internal:
        static void GotWindow(WIN Window) {
            wE(ManagedWIN(Window));
        }
};

Here ManagedWIN contains only safe .Net types.

Community
  • 1
  • 1
dbc
  • 104,963
  • 20
  • 228
  • 340