我的c#编码将消息发送到WM_COPYDATA
public static bool SendArgs(IntPtr targetHWnd, string args)
{
Win32.CopyDataStruct cds = new Win32.CopyDataStruct();
try
{
cds.cbData = (args.Length + 1) * 2;
cds.lpData = Win32.LocalAlloc(0x40, cds.cbData);
Marshal.Copy(args.ToCharArray(), 0, cds.lpData, args.Length);
cds.dwData = (IntPtr)1;
Win32.SendMessage(targetHWnd, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
}
finally
{
cds.Dispose();
}
return true;
}
我接收消息的代码是
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_COPYDATA:
{
COPYDATASTRUCT* copy_data = (COPYDATASTRUCT*)(lParam);
const char* str = (const char* )(copy_data->lpData);
/* Also fixed the parameter list for "%.*s" */
printf("Message (%u): %.*s\n", copy_data->dwData, (int)copy_data->cbData, str);
}
}
}
使用上面的代码我检索消息的第一个字符,而不是所有内容
答案 0 :(得分:3)
你的意思是这样的吗?
if (message == WM_COPYDATA)
{
COPYDATASTRUCT* copy_data = (COPYDATASTRUCT)(lparam);
const char* str = (const char*)(copy_data->lpData);
/* Also fixed the parameter list for "%.*s" */
printf("Message (%u): %.*s\n", copy_data->dwData, (int)copy_data->cbData, str);
}
当然,将copy_data->lpData
打印为字符串只有在确实是字符串数据时才有意义。
答案 1 :(得分:0)
我检索邮件的第一个字符,而不是所有内容。
这表示该字符串被编码为UTF-16,并且可以从C#代码中看到该字符串,该代码生成您发送的数据为UTF-16编码的消息。
另一方面,您的C代码将其视为8位ANSI编码。这就是C代码无法正确读取的原因。如果您的C代码将其视为UTF-16,那么您将获得所有内容。
您不能假设该字符串以空值终止,并且应使用cbData
来避免缓冲区溢出。
所以你可以改变你的C代码:
COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
int len = (cds->cbData/2)-1;
printf("Message (%u): %.*S\n", cds->dwData, len, cds->lpData);
请注意,%.*S
会将输入视为UTF-16编码字符串,并且打印的字符数不会超过len
。
我还假设您正在使用Microsoft的工具,因为S
格式类型是非标准的Microsoft特殊版本。如果你想要便携,那么有办法做到这一点,但我不确定你是否已经准备好解决这个问题了。