Я могу использовать код, чтобы получить сообщение, отправленное проектом C ++ (как deviceAttachedEvent
, так и WM_COPYDATA
). Я использовал FindWindow(NULL,L"WPFwindow name")
для получения дескриптора hwnd вместо GetProp
, поэтому убедитесь, что у вас правильный дескриптор окна. Вы можете использовать EnumPropsEx
, чтобы проверить, есть ли у вас свойство "DEVICE_CONNECTED_HWND"
Для WindowMessage deviceConnected
: вы отправляете указатель в текущем процессе, обычно это делает другой процесс. у вас нет разрешения на прямой доступ к этому адресу. Вам нужно использовать ReadProcessMemory
для чтения строковых данных по этому адресу.
Кроме того, обратите внимание на набор символов проекта. L"***"
не нужно приводить к LPCTSTR
, если набор символов - UNICODE, и использовать "***"
, если набор символов - многобайтовый набор символов. Или используйте макрос 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;
}