GetClipboardData() 只返回剪贴板数据的第一个字符
GetClipboardData() returning first character of clipboard data only
我正在尝试使用 GetClipboardData()
函数来检索剪贴板中的任何内容。为了测试这是否有效,我做了一个小函数,它应该将剪贴板打印到控制台 window.
我遇到的是,假设我复制 "test",我现在剪贴板上有 "test",我 运行 程序,程序显示 "t".
我尝试了一个 char 指针,一个 WCHAR 指针,直接类型转换为 std::cout
中的 char*
,以及 string
class、none其中似乎工作。 (它们都只显示字符串的第一个字符。)
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 text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
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一探究竟。
- GetClipBoardData needs to be passed to GlobalLock的return值接收一个指针。根据内存的类型(GMEM_MOVEABLE vs. GMEM_FIXED),句柄不一定与指向内存的指针相同。
- 剪贴板数据归剪贴板所有。剪贴板关闭后,从
GetClipboardData
编辑的 HGLOBAL
return 将不再有效。同样,由 GlobalLock
编辑的指针 return 仅在调用 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 下进行了详尽的解释。
我正在尝试使用 GetClipboardData()
函数来检索剪贴板中的任何内容。为了测试这是否有效,我做了一个小函数,它应该将剪贴板打印到控制台 window.
我遇到的是,假设我复制 "test",我现在剪贴板上有 "test",我 运行 程序,程序显示 "t".
我尝试了一个 char 指针,一个 WCHAR 指针,直接类型转换为 std::cout
中的 char*
,以及 string
class、none其中似乎工作。 (它们都只显示字符串的第一个字符。)
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 text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data.
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一探究竟。 - GetClipBoardData needs to be passed to GlobalLock的return值接收一个指针。根据内存的类型(GMEM_MOVEABLE vs. GMEM_FIXED),句柄不一定与指向内存的指针相同。
- 剪贴板数据归剪贴板所有。剪贴板关闭后,从
GetClipboardData
编辑的HGLOBAL
return 将不再有效。同样,由GlobalLock
编辑的指针 return 仅在调用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 下进行了详尽的解释。