GetClipboardData()仅返回剪贴板数据的第一个字符

时间:2018-03-05 10:21:10

标签: winapi clipboard

我正在尝试使用GetClipboardData()函数来检索剪贴板内的任何内容。为了测试这是否有效,我做了一个小函数,它应该将剪贴板打印到控制台窗口。

我所遇到的是,我说复制“测试”,我现在在剪贴板上“测试”,我运行程序,程序显示“t”。

我已经尝试了一个字符指针,一个WCHAR指针,直接转发char* std::cout内的stringif (!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; 类,但这些类似乎都不起作用。 (它们都只显示字符串的第一个字符。)

var d = new Date();
var currMonth = d.getMonth();
var currYear = d.getFullYear();
var startDate = new Date(currYear, currMonth, 1);

 $('#fromallSoDt').datepicker({
   autoclose: true,
   format: "dd M, yy"
   });

 $('#fromallSoDt').datepicker("setDate", startDate);

1 个答案:

答案 0 :(得分:5)

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查找。
  • 需要将GetClipBoardData的返回值传递给GlobalLock以接收指针。根据内存类型(GMEM_MOVEABLE与GMEM_FIXED),句柄不一定与指向内存的指针相同。
  • 剪贴板数据归剪贴板所有。关闭剪贴板后,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下详尽解释。

强制性阅读:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)