我正在尝试使用GetClipboardData()
函数来检索剪贴板内的任何内容。为了测试这是否有效,我创建了一个小函数,它应该将剪贴板打印到控制台窗口中。
我正在经历的是,我说复制“测试”,我现在在剪贴板上“测试”,我运行程序,程序显示“t”。
我已经尝试了一个字符指针,一个WCHAR指针,直接对char*
中的std::cout
进行类型转换,以及string
类,其中没有一个似乎有效。 (它们都只显示字符串的第一个字符。)
if (!OpenClipboard(NULL))
{
ExitWithError("Could not open clipboard."); //My own function, works fine, not the issue
}
HANDLE cbData = GetClipboardData(CF_UNICODETEXT);
if (!cbData)
{
ExitWithError("Could not retrieve clipboard data.");
}
CloseClipboard();
std::cout << (char*)cbData << std::endl;
如standard clipboard formats中所述:
CF_UNICODETEXT
:Unicode文本格式。每条线以回车/换行(CR-LF)组合结束。空字符表示数据的结尾。
Windows中的Unicode表示UTF-16LE。您的代码((char*)cbData
)将其重新解释为ASCII或ANSI。字符t
在UTF-16LE中编码为0x74 0x00
。第二个字节为空。这就是为什么std::cout
在打印t
之后就停止了。
要解决此问题,请改用std::wcout:
std::wcout << reinterpret_cast<const wchar_t*>(cbData) << std::endl;
另请注意,您的代码存在许多问题:
CF_UNICODETEXT
)保存数据,则不检查。打电话给IsClipboardFormatAvailable找出答案。HGLOBAL
返回的GetClipboardData
不再有效。同样,GlobalLock
返回的指针仅在调用GlobalUnlock
之前有效。如果您需要保留数据,请复制它。代码的固定版本可能如下所示:
if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
{
ExitWithError("Clipboard format not available.");
}
if (!OpenClipboard(NULL))
{
ExitWithError("Could not open clipboard."); // My own function, works fine,
// not the issue
}
HGLOBAL hglb = GetClipboardData(CF_UNICODETEXT);
if (!hglb)
{
CloseClipboard();
ExitWithError("Could not retrieve clipboard data.");
}
const wchar_t* lpStr = static_cast<const wchar_t*>(GlobalLock(hglb));
if (!lpStr)
{
CloseClipboard();
ExitWithError("Could not lock clipboard data.");
}
// Output data before closing the clipboard. Clipboard data is owned by the clipboard.
std::wcout << lpStr << std::endl;
GlobalUnlock(hglb);
CloseClipboard();
所有这些都在MSDN中的using the clipboard下详尽解释。