GetClipboardData (CF_UNICODETEXT);
GetClipboardData (CF_UNICODETEXT);
请告诉我,为什么我有这个问题:
-
如果剪贴板包含unicode字符(例如俄语),我只得到第一个选定的单词。空格前的第一个字
-
如果剪贴板不包含unicode字符(仅限英文),我将获得选定文本的第一个字符。
获取选定文本:
CStringA getClipboard()
{
CStringA strData;
if (OpenClipboard(NULL)){
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
char *pchData = (char*)GlobalLock(hClipboardData);
strData = pchData;
GlobalUnlock(hClipboardData);
CloseClipboard();
}
return strData;
}
设置文本:
bool setClipboard(CStringA textToclipboard)
{
bool success = true;
if (OpenClipboard(NULL)){
EmptyClipboard();
HGLOBAL hClipboardData;
size_t size = (textToclipboard.GetLength()+1) * sizeof(TCHAR);
hClipboardData = GlobalAlloc(NULL, size);
TCHAR* pchData = (TCHAR*)GlobalLock(hClipboardData);
memcpy(pchData, LPCTSTR(textToclipboard.GetString()), size);
SetClipboardData(CF_UNICODETEXT, hClipboardData);
GlobalUnlock(hClipboardData);
CloseClipboard();
}
return success;
}
获取和设置剪贴板内容。
CStringA str = getClipboard();
setClipboard(str);
CF_UNICODETEXT
使用UTF-16。在Windows上,wchar_t
数据元素用于UTF-16,但您的代码使用char
代替。CStringA
不兼容UTF-16。你在两个函数中的数据不匹配,这就是为什么你没有得到你所期望的结果。
一个解决方案是使用CStringW
代替CStringA
:
CStringW getClipboard()
{
CStringW strData;
if (OpenClipboard(NULL))
{
HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT);
if (hClipboardData)
{
WCHAR *pchData = (WCHAR*) GlobalLock(hClipboardData);
if (pchData)
{
strData = pchData;
GlobalUnlock(hClipboardData);
}
}
CloseClipboard();
}
return strData;
}
bool setClipboard(CStringW textToclipboard)
{
bool success = true;
if (OpenClipboard(NULL))
{
EmptyClipboard();
size_t size = (textToclipboard.GetLength()+1) * sizeof(WCHAR);
HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
if (hClipboardData)
{
WCHAR* pchData = (WCHAR*) GlobalLock(hClipboardData);
if (pchData)
{
memcpy(pchData, (WCHAR*) textToclipboard.GetString(), size);
GlobalUnlock(hClipboardData);
SetClipboardData(CF_UNICODETEXT, hClipboardData);
}
}
CloseClipboard();
}
return success;
}
如果你需要坚持使用CStringA
,那么:
使用
CF_TEXT
代替CF_UNICODETEXT
,让剪贴板为你处理Ansi和Unicode之间的转换:CStringA getClipboard() { CStringA strData; if (OpenClipboard(NULL)) { HANDLE hClipboardData = GetClipboardData(CF_TEXT); if (hClipboardData) { CHAR *pchData = (CHAR*) GlobalLock(hClipboardData); if (pchData) { strData = pchData; GlobalUnlock(hClipboardData); } } CloseClipboard(); } return strData; } bool setClipboard(CStringA textToclipboard) { bool success = true; if (OpenClipboard(NULL)) { EmptyClipboard(); size_t size = (textToclipboard.GetLength()+1) * sizeof(CHAR); HGLOBAL hClipboardData = GlobalAlloc(NULL, size); if (hClipboardData) { CHAR* pchData = (CHAR*) GlobalLock(hClipboardData); if (pchData) { memcpy(pchData, (CHAR*) textToclipboard.GetString(), size); GlobalUnlock(hClipboardData); SetClipboardData(CF_TEXT, hClipboardData); } } CloseClipboard(); } return success; }
使用
CF_UNICODETEXT
时手动转换为/从UTF-16:CStringA getClipboard() { CStringW strData; if (OpenClipboard(NULL)) { HANDLE hClipboardData = GetClipboardData(CF_UNICODETEXT); if (hClipboardData) { WCHAR *pchData = (WCHAR*) GlobalLock(hClipboardData); if (pchData) { strData = pchData; GlobalUnlock(hClipboardData); } } CloseClipboard(); } return CStringA((WCHAR*)strData.GetString()); } bool setClipboard(CStringA strData) { CStringW textToclipboard((CHAR*)strData.GetString()); bool success = true; if (OpenClipboard(NULL)) { EmptyClipboard(); size_t size = (textToclipboard.GetLength()+1) * sizeof(WCHAR); HGLOBAL hClipboardData = GlobalAlloc(NULL, size); if (hClipboardData) { WCHAR* pchData = (WCHAR*) GlobalLock(hClipboardData); if (pchData) { memcpy(pchData, (WCHAR*) textToclipboard.GetString(), size); GlobalUnlock(hClipboardData); SetClipboardData(CF_UNICODETEXT, hClipboardData); } } CloseClipboard(); } return success; }
另一个解决方案是使用CString
代替CStringA
或CStringW
,然后使用CF_TEXT
或CF_UNICODETEXT
取决于TCHAR
是Ansi还是Unicode:
#ifdef UNICODE
#define CF_TEXT_T CF_UNICODETEXT
#else
#define CF_TEXT_T CF_TEXT
#endif
CString getClipboard()
{
CString strData;
if (OpenClipboard(NULL))
{
HANDLE hClipboardData = GetClipboardData(CF_TEXT_T);
if (hClipboardData)
{
TCHAR *pchData = (TCHAR*) GlobalLock(hClipboardData);
if (pchData)
{
strData = pchData;
GlobalUnlock(hClipboardData);
}
}
CloseClipboard();
}
return strData;
}
bool setClipboard(CString textToclipboard)
{
bool success = true;
if (OpenClipboard(NULL))
{
EmptyClipboard();
size_t size = (textToclipboard.GetLength()+1) * sizeof(TCHAR);
HGLOBAL hClipboardData = GlobalAlloc(NULL, size);
if (hClipboardData)
{
TCHAR* pchData = (TCHAR*) GlobalLock(hClipboardData);
if (pchData)
{
memcpy(pchData, (TCHAR*) textToclipboard.GetString(), size);
GlobalUnlock(hClipboardData);
SetClipboardData(CF_TEXT_T, hClipboardData);
}
}
CloseClipboard();
}
return success;
}
它们都是Unicode…
但是在Unicode中,多于一个字节表示一个字符。例如,一个字符可能使用2个字节。因此:
当它是俄语时,字符串就像
' '
----
0x04 0x3F 0x04 0x40 0x04 0x38 0x04 0x32 0x04 0x35 0x04 0x42 0x00 0x20
~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~
п р и в е т space
一直读到空格
当它是英文时,字符串类似于
' '
----
0x00 0x48 0x00 0x65 0x00 0x6C 0x00 0x6C 0x00 0x6F 0x00 0x20
~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~
H e l l o space
它什么也没读。(如果你先读,是因为存储字节的顺序,LE或BE)
注意:也许我在选择单词(Unicode, UTF,…)时不够精确