Tôi có nó hoạt động.
Cách tiếp cận đơn giản là tuần tự hóa cấu trúc thành một chuỗi và chuyển một chuỗi. Blog swhistlesoft hữu ích http://www.swhistlesoft.com/blog/2011/11/19/1636-wm_copydata-with-net-and-c
Điều này có thể đủ để cung cấp thông điệp đơn giản. Cấu trúc có thể được xây dựng lại ở đầu kia nếu cần thiết.
Nếu một cấu trúc có số chuỗi bất kỳ được sắp xếp như sau thì nó phải là kích thước cố định, đó là điều chính tôi không nhận được. Các
MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 9)
cơ bản thiết lập kích thước để phù hợp với C++ kích thước mà trong trường hợp của chúng tôi là một TCHAR szTest [9];
Để chuyển a.struct Net qua WM_COPYDATA từ C# C++ (/ cli) tôi phải làm như sau:
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
static extern bool SetForegroundWindow(IntPtr hWnd);
public static uint WM_COPYDATA = 74;
//from swhistlesoft
public static IntPtr IntPtrAlloc<T>(T param)
{
IntPtr retval = System.Runtime.InteropServices.Marshal.AllocHGlobal(System.Runtime.InteropServices.Marshal.SizeOf(param));
System.Runtime.InteropServices.Marshal.StructureToPtr(param, retval, false);
return (retval);
}
//from swhistlesoft
public static void IntPtrFree(IntPtr preAllocated)
{
if (IntPtr.Zero == preAllocated) throw (new Exception("Go Home"));
System.Runtime.InteropServices.Marshal.FreeHGlobal(preAllocated);
preAllocated = IntPtr.Zero;
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
public uint dwData;
public int cbData;
public IntPtr lpData;
}
/// <summary>
/// Dot net version of AppInfo structure. Any changes to the structure needs reflecting here.
/// struct must be a fixed size for marshalling to work, hence the SizeConst entries
/// </summary>
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
struct AppInfoDotNet
{
public int nVersion;
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 9)]
public string test;
};
Để gửi một chuỗi:
COPYDATASTRUCT cd = new COPYDATASTRUCT();
cd.dwData = 2;
cd.cbData = parameters.Length + 1;
cd.lpData = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(parameters);
IntPtr cdBuffer = IntPtrAlloc(cd);
messageReceived = ((int)SendMessage(targetProcess.MainWindowHandle, WM_COPYDATA, IntPtr.Zero, cdBuffer)) != 0;
Tiếp nhận chuỗi trong C++:
else if(pCDS->dwData == 2)
{
//copydata message
CString csMessage = (LPCTSTR)pCDS->lpData;
OutputDebugString("Copydata message received: " + csMessage);
}
Để gửi cấu trúc:
AppInfoDotNet appInfo = new AppInfoDotNet();
appInfo.test = "a test";
COPYDATASTRUCT cds3;
cds3.dwData = 1;
cds3.cbData = System.Runtime.InteropServices.Marshal.SizeOf(appInfo);
IntPtr structPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(System.Runtime.InteropServices.Marshal.SizeOf(appInfo));
System.Runtime.InteropServices.Marshal.StructureToPtr(appInfo, structPtr, false);
cds3.lpData = structPtr;
IntPtr iPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(System.Runtime.InteropServices.Marshal.SizeOf(cds3));
System.Runtime.InteropServices.Marshal.StructureToPtr(cds3, iPtr, false);
messageReceived = ((int)SendMessage(targetProcess.MainWindowHandle, WM_COPYDATA, IntPtr.Zero, iPtr)) != 0;
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(iPtr);
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(structPtr);
Để lại ceive struct trong C++:
LRESULT CMainFrame::OnCopyData(WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = FALSE;
COPYDATASTRUCT *pCDS = (COPYDATASTRUCT*)lParam;
//Matching message type for struct
if(pCDS->dwData == 1)
{
AppInfo *pAppInfo = (AppInfo*)pCDS->lpData
lResult = true;
}
Xin lưu ý đây là code demo và nhu cầu làm việc trong điều kiện của phong cách, ngoại lệ xử lý vv, vv ...
Cảm ơn. Đối với cấu trúc tùy chỉnh marshalling trong WM_COPYDATA, ví dụ của bạn là chỉ làm việc được tìm thấy trên trang web này. –