[英]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++ 项目( deviceAttachedEvent
和WM_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.