use*_*809 5 c++ unicode clipboard
请告诉我,为什么我会遇到这个问题:
如果剪贴板包含unicode字符(eq russian)我只得到第一个选定的单词."空间"字符前的第一个字.
如果剪贴板不包含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;
}
Run Code Online (Sandbox Code Playgroud)
设置文字:
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;
}
Run Code Online (Sandbox Code Playgroud)
只需获取并设置剪贴板内容.
CStringA str = getClipboard();
setClipboard(str);
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
如果你需要坚持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;
}
Run Code Online (Sandbox Code Playgroud)使用时手动转换为UTF-16 /从UTF-16转换CF_UNICODETEXT:
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;
}
Run Code Online (Sandbox Code Playgroud)另一个解决方案是使用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;
}
Run Code Online (Sandbox Code Playgroud)
它们都是Unicode ......
但在Unicode中,更多的是一个字节代表一个字符.例如,可能有2个字节用于字符.因此:
当它是俄语时,字符串就像
'\0'
----
0x04 0x3F 0x04 0x40 0x04 0x38 0x04 0x32 0x04 0x35 0x04 0x42 0x00 0x20
~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~
? ? ? ? ? ? space
Run Code Online (Sandbox Code Playgroud)
它读到空间.
当它是英文时,字符串就像
'\0'
----
0x00 0x48 0x00 0x65 0x00 0x6C 0x00 0x6C 0x00 0x6F 0x00 0x20
~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~ ~~~~~~~~~
H e l l o space
Run Code Online (Sandbox Code Playgroud)
它什么都没读.(如果你先读,那是因为存储字节,LE或BE的顺序)
注意:也许我不精确选择单词(Unicode,UTF,...)
| 归档时间: |
|
| 查看次数: |
10983 次 |
| 最近记录: |