Windows剪贴板不会保留ASCII字符

时间:2018-08-28 23:09:35

标签: c++ c ascii special-characters clipboard

我正在为TS3客户端编写插件,但是遇到了问题...

其中一个频道名称带有一个特殊符号(╠),这是我认为是扩展的ascii表中的一个特殊字符。

在将其记录为INSIDE teampeak时,该字符显示正常,但是当尝试使用其C接口将其复制到Windows剪贴板时,它将返回一个完全不同的字符(â)。

在我阅读到扩展的ascii表使用的字节数比常规char占用的字节更多时,我尝试将其转换为WCHAR,但这也不起作用。

我使用以下代码将char *复制到剪贴板中,该剪贴板在某个地方找到,并使用使用WCHAR的其他代码进行了更改:

void SaveClipboard(char* tx)
{
    WCHAR text[140];
    swprintf(text, 140, L"%hs", tx);

    if(OpenClipboard(NULL))
    {
        EmptyClipboard();
        HGLOBAL global = GlobalAlloc(GMEM_DDESHARE, 2 * (wcslen(text) + 1)); //text size + \0 character

        WCHAR* pchData;
        pchData = (WCHAR*)GlobalLock(global);
        wcscpy(pchData, text);
        GlobalUnlock(pchData);

        SetClipboardData(CF_UNICODETEXT, global);
        CloseClipboard();
    }
}

1 个答案:

答案 0 :(得分:4)

wchar_tUTF-16编码的,但是您获得的数据是UTF-8编码的。您无需在这两种编码之间进行转换,只需重新解释字节即可。

看一下这些字符的代码点,应该很清楚正在发生的事情:的UTF-8代码点是0xE2 0x95 0xA0,而â的UTF-16代码点是0x00 0xE2,而的UTF-16代码点是0x25 0x60

swprintf(text, 140, L"%hs", tx); <-这仅将每个char转换为wchar_t,将3字节的UTF-8代码点0xE2 0x95 0xA0变成三个2字节的{{1 }}代码点:UTF-160x00 0xE20x00 0x95

要从0x00 0xA0获取0x25 0x60,您需要实际转换数据:

0xE2 0x95 0xA0

或者,由于您已经在使用WINAPI,因此可以使用MultiByteToWideChar

std::wstring_convert<std::codecvt_utf8_utf16<char16_t>> converter;
std::wstring text = converter.from_bytes(tx);