如何从C++;MFC到WPF C#应用程序?

如何从C++;MFC到WPF C#应用程序?,c#,c++,wpf,winapi,C#,C++,Wpf,Winapi,我需要从MFC(C++)向WPF(C#)应用程序发送自定义消息/通知。 在Internet上,从C到C++应用程序的消息发送有一些问题。 我已经尝试实现我的案例,然后是那些文章,但无法接收来自WPF的消息 我尝试过的内容如下: 在MFC应用程序中,我尝试使用PostMessage和SendMessage发送消息 但这些都不能从WPF应用程序接收。 UINT deviceConnected = 0; deviceConnected = RegisterWindowMessage(L"DE

我需要从MFC(C++)向WPF(C#)应用程序发送自定义消息/通知。 在Internet上,从C到C++应用程序的消息发送有一些问题。 我已经尝试实现我的案例,然后是那些文章,但无法接收来自WPF的消息

我尝试过的内容如下:

在MFC应用程序中,我尝试使用PostMessage和SendMessage发送消息 但这些都不能从WPF应用程序接收。

UINT deviceConnected = 0;
deviceConnected = RegisterWindowMessage(L"DEVICE_CONNECTED");
HWND dstWnd = (HWND)GetProp(GetDesktopWindow(), L"DEVICE_CONNECTED_HWND");

const char* message = "This is a custom message";
::PostMessage(dstWnd, deviceConnected, 0, (LPARAM)(LPCTSTR)message);
::SendMessage(dstWnd, deviceConnected, 0, (LPARAM)(LPCTSTR)message);
我也尝试过WM_COPYDATA:

LPCTSTR lpszString = (LPCTSTR)L"This is second message";
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = sizeof(TCHAR) * (_tcslen(lpszString) + 1);
cds.lpData = (PVOID)lpszString;
::PostMessage(dstWnd, WM_COPYDATA, 0, (LPARAM)(LPVOID)&cds); 
::SendMessage(dstWnd, WM_COPYDATA, 0, (LPARAM)(LPVOID)&cds);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
private UInt32 deviceAttachedEvent = 0;
const int WM_COPYDATA = 0x4A;
    
protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    HwndSource hwndSource = HwndSource.FromVisual(this) as HwndSource;
    if (hwndSource != null)
    {
        hwndSource.AddHook(new HwndSourceHook(WndProc));
    }
}

private IntPtr WndProc(IntPtr hwnd, int msgId, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    IntPtr result = IntPtr.Zero;

    //if the deviceAttachedEvent message id has not been registered...
    if (deviceAttachedEvent == 0)
        deviceAttachedEvent  = RegisterWindowMessage("DEVICE_CONNECTED");

    if ((UInt32)msgId == deviceAttachedEvent )
    {
        //string msg = Marshal.PtrToStringAuto(lParam);
        Console.WriteLine("Received message from MFC");
        //Console.WriteLine(msg);
    }

    if (msgId == WM_COPYDATA)
    {
        COPYDATASTRUCT cds = new COPYDATASTRUCT();
        cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam,typeof(COPYDATASTRUCT));
        if (cds.cbData > 0)
        {
            byte[] data = new byte[cds.cbData];
            Marshal.Copy(cds.lpData, data, 0, cds.cbData);
            Encoding unicodeStr = Encoding.ASCII;
            char[] myString = unicodeStr.GetChars(data);
            string returnText = new string(myString);
            MessageBox.Show("ACK Received: " + returnText);
        }
    }
    
    return result;
}
下面是WPF代码示例:

LPCTSTR lpszString = (LPCTSTR)L"This is second message";
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.cbData = sizeof(TCHAR) * (_tcslen(lpszString) + 1);
cds.lpData = (PVOID)lpszString;
::PostMessage(dstWnd, WM_COPYDATA, 0, (LPARAM)(LPVOID)&cds); 
::SendMessage(dstWnd, WM_COPYDATA, 0, (LPARAM)(LPVOID)&cds);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
private UInt32 deviceAttachedEvent = 0;
const int WM_COPYDATA = 0x4A;
    
protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    HwndSource hwndSource = HwndSource.FromVisual(this) as HwndSource;
    if (hwndSource != null)
    {
        hwndSource.AddHook(new HwndSourceHook(WndProc));
    }
}

private IntPtr WndProc(IntPtr hwnd, int msgId, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    IntPtr result = IntPtr.Zero;

    //if the deviceAttachedEvent message id has not been registered...
    if (deviceAttachedEvent == 0)
        deviceAttachedEvent  = RegisterWindowMessage("DEVICE_CONNECTED");

    if ((UInt32)msgId == deviceAttachedEvent )
    {
        //string msg = Marshal.PtrToStringAuto(lParam);
        Console.WriteLine("Received message from MFC");
        //Console.WriteLine(msg);
    }

    if (msgId == WM_COPYDATA)
    {
        COPYDATASTRUCT cds = new COPYDATASTRUCT();
        cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam,typeof(COPYDATASTRUCT));
        if (cds.cbData > 0)
        {
            byte[] data = new byte[cds.cbData];
            Marshal.Copy(cds.lpData, data, 0, cds.cbData);
            Encoding unicodeStr = Encoding.ASCII;
            char[] myString = unicodeStr.GetChars(data);
            string returnText = new string(myString);
            MessageBox.Show("ACK Received: " + returnText);
        }
    }
    
    return result;
}

提前感谢。< /P> < P>我可以使用代码获取C++项目发送的消息(两者都是代码> > Deice附件De/ToC>和<代码> WMYCopyDATAs/Cuff>。 我使用了

FindWindow(NULL,L“WPFwindow name”)
来获取hwnd句柄,而不是
GetProp
,因此请确保获得了正确的窗口句柄。您可以使用测试您是否具有
“DEVICE\u CONNECTED\u HWND”

对于WindowMessage
已连接的设备
: 您正在当前进程中发送指针,另一进程通常没有直接访问此地址的权限。您需要使用读取此地址中的字符串数据

此外,请注意项目的字符集<如果字符集是UNICODE,则code>L“***”不需要强制转换为
LPCTSTR
,如果字符集是多字节字符集,则使用
“***”
。或者使用
文本(“”)

此外,您还发送了一个宽字节字符串
L“这是第二条消息”
,然后在读取时设置
Encoding.ASCII
,这将截断字符串,如下所示:

因此,我的样本是: C++:


< >我可以使用代码来获得C++项目发送的消息(两者都是代码> > Deice附件De/ToC>和<代码> WMyCopyDATABO/<代码>。 我使用了
FindWindow(NULL,L“WPFwindow name”)
来获取hwnd句柄,而不是
GetProp
,因此请确保获得了正确的窗口句柄。您可以使用测试您是否具有
“DEVICE\u CONNECTED\u HWND”

对于WindowMessage
已连接的设备
: 您正在当前进程中发送指针,另一进程通常没有直接访问此地址的权限。您需要使用读取此地址中的字符串数据

此外,请注意项目的字符集<如果字符集是UNICODE,则code>L“***”不需要强制转换为
LPCTSTR
,如果字符集是多字节字符集,则使用
“***”
。或者使用
文本(“”)

此外,您还发送了一个宽字节字符串
L“这是第二条消息”
,然后在读取时设置
Encoding.ASCII
,这将截断字符串,如下所示:

因此,我的样本是: C++:


不清楚“无法接收消息”是什么意思。它不能编译吗?它是否编译但链接失败?它是否编译并链接,但在运行时失败并出现错误?它失败了没有错误吗?消息是否真的通过了,但数据不是您所期望的?还有什么吗?@yeasir007如果问题只与接收WPF上的消息有关,您是否已隔离?i、 e.您是否尝试过从本机C/C++/MFC应用程序切换到其他应用程序?您还可以在此处查看其他进程间通信方法:@IInspectable,消息已从MFC应用程序发送,但此消息未从WPF WndProg接收。您是否验证了已注册的消息具有相同的(非零)值?您是否验证了两侧的
HWND
s是否相同?还要确保了解,系统不会跨进程边界封送指向0范围以外消息的数据<代码>WM_用户。已注册邮件超出该范围。已注册邮件的调试值从两端都相同。我不明白你的意思,怎么两边的HWND都是一样的。你能说清楚吗。注册的消息值范围是一个正数,如10079。不清楚“无法接收消息”是什么意思。它不能编译吗?它是否编译但链接失败?它是否编译并链接,但在运行时失败并出现错误?它失败了没有错误吗?消息是否真的通过了,但数据不是您所期望的?还有什么吗?@yeasir007如果问题只与接收WPF上的消息有关,您是否已隔离?i、 e.您是否尝试过从本机C/C++/MFC应用程序切换到其他应用程序?您还可以在此处查看其他进程间通信方法:@IInspectable,消息已从MFC应用程序发送,但此消息未从WPF WndProg接收。您是否验证了已注册的消息具有相同的(非零)值?您是否验证了两侧的
HWND
s是否相同?还要确保了解,系统不会跨进程边界封送指向0范围以外消息的数据<代码>WM_用户。已注册邮件超出该范围。已注册邮件的调试值从两端都相同。我不明白你的意思,怎么两边的HWND都是一样的。你能说清楚吗。注册的消息值范围是一个正数,如10079。谢谢@Drake。这个窗口处理程序才是真正的问题。谢谢@Drake。这个窗口处理程序才是真正的问题。