c++ - Windows 剪贴板不会保留 ASCII 字符

标签 c++ c ascii special-characters clipboard

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

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

当将其记录在 groupspeak 中时,该字符显示正常,但是当尝试使用其 C 接口(interface)将其复制到 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();
    }
}

最佳答案

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 字节 UTF-16代码点:0x00 0xE2 , 0x00 0x950x00 0xA0 .

获取0x25 0x60来自0xE2 0x95 0xA0您需要实际转换数据:

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

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

WCHAR text[140];
int length = MultiByteToWideChar(CP_UTF8, 0, tx, -1, (LPWSTR)text, 140);

关于c++ - Windows 剪贴板不会保留 ASCII 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52067338/

相关文章:

c++ - 弄清楚网络、十六进制和 ascii 如何交互

java - 有可用的聊天机器人框架吗?

c++ - 定义 "library-safe"代码的概念

无法计算 .c 文件中的 '|' 符号

你能把 ASCII 码转换成 C 中的字符吗?

java - 停止将十进制转换为 ascii

c++ - 是否可以测试两个迭代器是否指向同一个对象?

c++ - 解压可变模板时避免 "recursive"函数调用直到运行时条件

c++ - 从 C++ 访问 ListElement (QML) 颜色

c - 一个ip头的布局和网络编程