我想將一些C++代碼移植到C#中,而我需要做的其中一件事是使用PostMessage
將字節數組傳遞給另一個進程的窗口。我試圖得到源代碼給其它程序,所以我可以看到正是它的期望,但在此期間,這裏是原來的C++代碼如下所示:PostMessage的字節數組封送
unsigned long result[5] = {0};
//Put some data in the array
unsigned int res = result[0];
Text winName = "window name";
HWND hWnd = FindWindow(winName.getConstPtr(), NULL);
BOOL result = PostMessage(hWnd, WM_COMMAND, 10, res);
而且這是我現在有:
[DllImport("User32.dll", SetLastError = true, EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("User32.dll", SetLastError = true, EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
public byte[] lpData;
}
public const int WM_COPYDATA = 0x4A;
public static int sendWindowsByteMessage(IntPtr hWnd, int wParam, byte[] data)
{
int result = 0;
if (hWnd != IntPtr.Zero)
{
int len = data.Length;
COPYDATASTRUCT cds;
cds.dwData = wParam;
cds.lpData = data;
cds.cbData = len;
result = SendMessage(hWnd, WM_COPYDATA, wParam, ref cds);
}
return result;
}
//*****//
IntPtr hWnd = MessageHelper.FindWindow(null, windowName);
if (hWnd != IntPtr.Zero)
{
int result = MessageHelper.sendWindowsByteMessage(hWnd, wParam, lParam);
if (result == 0)
{
int errCode = Marshal.GetLastWin32Error();
}
}
注意,我不得不使用C#中使用C++ PostMessage
到SendMessage
切換。
所以現在發生的是,我得到的結果和errCode都是0,我認爲這意味着消息沒有處理 - 實際上看着另一個應用程序,我沒有看到預期的響應。我已經驗證了hWnd != IntPtr.Zero
,所以我認爲這條消息被髮布到正確的窗口,但是消息數據是錯誤的。任何想法我做錯了什麼?
更新
我仍然沒有在評論中嘗試建議後任何運氣。這就是我目前有:
[DllImport("User32.dll", SetLastError = true)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}
public struct BYTEARRDATA
{
public byte[] data;
}
public static IntPtr IntPtrAlloc<T>(T param)
{
IntPtr retval = Marshal.AllocHGlobal(Marshal.SizeOf(param));
Marshal.StructureToPtr(param, retval, false);
return (retval);
}
public static void IntPtrFree(IntPtr preAllocated)
{
//Ignores errors if preAllocated is IntPtr.Zero!
if (IntPtr.Zero != preAllocated)
{
Marshal.FreeHGlobal(preAllocated);
preAllocated = IntPtr.Zero;
}
}
BYTEARRDATA d;
d.data = data;
IntPtr buffer = IntPtrAlloc(d);
COPYDATASTRUCT cds;
cds.dwData = new IntPtr(wParam);
cds.lpData = buffer;
cds.cbData = Marshal.SizeOf(d);
IntPtr copyDataBuff = IntPtrAlloc(cds);
IntPtr r = SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, copyDataBuff);
if (r != IntPtr.Zero)
{
result = r.ToInt32();
}
IntPtrFree(copyDataBuff);
copyDataBuff = IntPtr.Zero;
IntPtrFree(buffer);
buffer = IntPtr.Zero;
這是一個64位進程試圖聯繫一個32位的過程,所以有可能是一些有,但我不知道是什麼。
爲什麼你必須從'PostMessage'切換到'SendMessage'? – 2011-05-31 14:48:55
看看我的[上一個問題]這個答案(http://stackoverflow.com/questions/6131636/send-byte-from-c-via-win32-sendmessage/6131886#6131886) - 長話短說,PostMessage是異步的,SendMessage是同步的,並且呼叫需要是同步的,以便數據對於呼叫的長度有效。 – 2011-05-31 18:30:58
嘗試將數據從64位進程傳遞到32位進程將會是一個問題。你在'copyDataBuff'中傳遞的指針是64位,但是你將它傳遞給一個32位的進程,它不知道如何處理它。如果兩個進程都是32位,這個代碼是否工作? – 2011-05-31 20:07:57