【发布时间】:2020-11-01 07:01:31
【问题描述】:
我需要将自定义消息/通知从 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;
}
提前致谢。
【问题讨论】:
-
不清楚,“无法接收消息”是什么意思。编译失败了吗?它是否编译但无法链接?它是否编译和链接但在运行时失败并出现错误?它会在没有错误的情况下失败吗?消息是否真的通过了,但数据不是您所期望的?还有什么?
-
@yeasir007 如果问题仅与在 WPF 上接收消息有关,您是否已隔离?即您是否尝试过从本机 C/C++/MFC 应用程序到另一个应用程序?您还可以在这里查看替代的进程间通信方法:docs.microsoft.com/en-us/windows/win32/ipc/…
-
@IInspectable,消息已从 MFC 应用程序发送,但未从 WPF WndProg 收到此消息。
-
您是否验证了注册的消息具有相同的(非零)值?您是否验证过,
HWNDs 两边是否相同?还要确保理解,系统不会跨进程边界为范围 0 ..WM_USER之外的消息编组指向数据。已注册的消息超出该范围。 -
注册消息的调试值在两端是相同的。双方的 HWND 如何相同,我没有明白你的意思。你能说清楚吗?并且注册的消息值范围是一个正值,比如 10079。