问题描述
|
我正在努力将某些代码从c ++移植到c#,并且在使PostMessage在c#应用程序中工作方面遇到一些麻烦。我在MFC方面还不太好,我认为我在犯一些基本错误。在c ++代码中发生的是将字节数组发布到窗口:
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);
我正在使用以下c#代码(基于此处的代码)来尝试执行相同的操作:
[DllImport(\"User32.dll\",EntryPoint = \"FindWindow\")]
public static extern Int32 FindWindow(String lpClassName,String lpWindowName);
[DllImport(\"User32.dll\",EntryPoint = \"PostMessage\")]
public static extern int PostMessage(int hWnd,int Msg,int wParam,ref copYDATASTRUCT lParam);
[StructLayout(LayoutKind.Sequential)]
public struct copYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.SafeArray)]
public byte[] lpData;
}
public static int sendWindowsByteMessage(int hWnd,byte[] data)
{
int result = 0;
if (hWnd > 0)
{
int len = data.Length;
copYDATASTRUCT cds;
cds.dwData = (IntPtr)100;
cds.lpData = data;
cds.cbData = len + 1;
result = PostMessage(hWnd,WM_copYDATA,wParam,ref cds);
}
return result;
}
byte[] result = getResults();
int hWnd = MessageHelper.FindWindow(null,\"window name\");
int status = MessageHelper.sendWindowsByteMessage(hWnd,result);
status的值始终为0,根据PostMessage的文档,这表示失败。关于我正在犯的错误(可能很简单)的任何指示?
解决方法
WM_ COPYDATA
必须发送而不是张贴。
我不确定您的byte []封送处理是否正确。
,这是我成功使用的相同逻辑的一个版本:
[StructLayout(LayoutKind.Sequential)]
internal class COPYDATASTRUCT
{
internal uint dwData;
internal uint cbData;
internal IntPtr lpData;
}
// send DATA packet
internal static void SendData(IntPtr hWnd,uint dwData,DATA infos)
{
// get pointer to DATA block
IntPtr infoMem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DATA)));
Marshal.StructureToPtr(infos,infoMem,false);
// construct COPYDATASTRUCT to point to DATA block
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.dwData = dwData;
cds.lpData = infoMem;
cds.cbData = (uint)Marshal.SizeOf(typeof(DATA));
// get pointer to COPYDATASTRUCT block
IntPtr cdsMem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(COPYDATASTRUCT)));
Marshal.StructureToPtr(cds,cdsMem,false);
// send message with block pointer to other process
SendMessage(hWnd,WM_COPYDATA,(uint)cdsMem.ToInt32());
// Free allocated memory
Marshal.FreeHGlobal(cdsMem);
Marshal.FreeHGlobal(infoMem);
}
如果目标窗口在另一个进程中,则需要使用HGlobal内存。我不确定UnmanagedType.SafeArray是否为您做到了。
,由于窗口句柄无效,PostMessage可能失败。调用GetLastError找出失败的原因。您实际上将在这里使用SendMessage-仅保证在调用期间分配缓冲区,而PostMessage是异步的-在发布消息后返回,并且在目标窗口proc被释放之前,您的cds结构可能会释放调用。如果您需要使用PostMessage,则必须明确分配一个非托管缓冲区,将数据复制到该缓冲区中,然后将其用于调用。