如何从C中的COPYDATASTRUCT复制消息?

时间:2013-05-16 15:02:53

标签: c

我的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);
}
}
}

使用上面的代码我检索消息的第一个字符,而不是所有内容

2 个答案:

答案 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特殊版本。如果你想要便携,那么有办法做到这一点,但我不确定你是否已经准备好解决这个问题了。