簡體   English   中英

如何將自定義消息從 C++ MFC 發送到 WPF ZD7EFA19FBE7D3972FD5ADB6024223D7 應用程序?

[英]How to send Custom Message from C++ MFC to WPF C# application?

我需要將自定義消息/通知從 MFC(C++) 發送到 WPF(C#) 應用程序。 互聯網上有一些關於從 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);

下面是 WPF 代碼示例:

[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;
}

提前致謝。

我可以使用代碼獲取 C++ 項目( deviceAttachedEventWM_COPYDATA )發送的消息。 我使用FindWindow(NULL,L"WPFwindow name")來獲取 hwnd 句柄,而不是GetProp ,因此請確保您擁有正確的 window 句柄。 您可以使用EnumPropsEx來測試您是否具有"DEVICE_CONNECTED_HWND"的屬性

對於 WindowMessage deviceConnected :你在當前進程中發送一個指針,另一個進程通常沒有權限直接訪問這個地址。 您需要使用ReadProcessMemory來讀取該地址中的字符串數據。

另外,請注意項目的字符集。 如果字符集是 UNICODE,則L"***"不需要轉換為LPCTSTR ,如果字符集是多字節字符集,則使用"***" 或者使用TEXT("")宏。

此外,您發送了一個寬字節字符串L"This is second message" ,然后在讀取時設置Encoding.ASCII ,這將截斷字符串,如:

在此處輸入圖像描述

所以我的樣本是:C++:

#include <windows.h>
#include <iostream>
#include <tchar.h>
int main()
{
    UINT deviceConnected = 0;
    deviceConnected = RegisterWindowMessage(L"DEVICE_CONNECTED");
    HWND dstWnd = FindWindow(NULL,L"MainWindow");

    const wchar_t* message = TEXT("This is a custom message");
    ::SendMessage(dstWnd, deviceConnected, 0, (LPARAM)(LPCTSTR)message);

    LPCTSTR lpszString = TEXT("This is second message");
    COPYDATASTRUCT cds;
    cds.dwData = 0;
    cds.cbData = sizeof(TCHAR) * (_tcslen(lpszString) + 1);
    cds.lpData = (PVOID)lpszString;

    ::SendMessage(dstWnd, WM_COPYDATA, 0, (LPARAM)(LPVOID)&cds);

}

在 wpf 中:

   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)
        {
            //OpenProcess + PROCESS_VM_READ
            //ReadProcessMemory + lParam
            Console.WriteLine("Received message from MFC");
        }

        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.Unicode;
                char[] myString = unicodeStr.GetChars(data);
                string returnText = new string(myString);
                MessageBox.Show("ACK Received: " + returnText);
            }
        }

        return result;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM