-1

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

我接收消息的 c 代码是

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

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

4

2 回答 2

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为字符串只有在它确实是字符串数据时才有意义。

于 2013-05-16T15:16:45.353 回答
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 特殊格式。如果你想要便携,那么有办法做到这一点,但我不确定你是否已经准备好解决这个问题。

于 2013-05-17T06:11:06.360 回答