我正在为 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_t
是 UTF-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 0x95
和0x00 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/