在 C++ 中的 SetClipboardData() 之后粘贴不包括记事本的换行符

Pasting after SetClipboardData() in C++ does not include newlines for Notepad

我正在开发一些软件,可以将大字符串复制到 windows 剪贴板,然后粘贴到其他软件中。在其他软件中粘贴不成功,当我粘贴到记事本中时,初始字符串中的换行符消失了,这就是为什么在其他软件中粘贴失败的原因。我知道这一点,因为当我将换行符重新添加到记事本并进行复制时,粘贴然后在其他程序中工作。当我粘贴到写字板时,换行符神秘地在那里。

我在 C++ 中使用 CF_TEXT 剪贴板格式类型的 SetClipboardData()。我试过使用 CF_OEMTEXT、CF_DSPTEXT,但这些都不起作用。我看到一些关于电子表格 CF_SYLK(符号 Link)的文档,因为我粘贴的软件类似于电子表格,但我也无法让它工作。下面是我复制到剪贴板的代码。

void ClipBoardManager::CopyExcelStringToClipBoard(std::string excel_str)
{
    OpenClipboard(nullptr);
    EmptyClipboard();
    HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, excel_str.size() + 1);
    if (!hg) {
        CloseClipboard();
        return;
    }
    memcpy(GlobalLock(hg), excel_str.c_str(), excel_str.size() + 1);
    GlobalUnlock(hg);
    SetClipboardData(CF_TEXT, hg);
    CloseClipboard();
    GlobalFree(hg);

}

感谢任何帮助。

excel_str 必须有 CRLF 行结尾。下面是将字符串转换为正确格式的示例代码:

string replaceAll(string in, string replaceIn, string replaceOut)
{
    size_t pos = 0;
    while(pos < in.size())
    {
        size_t pos2 = in.find(replaceIn, pos);
        if(pos2 != string::npos)
        {
            in.replace(in.begin() + pos2, in.begin() + pos2 + replaceIn.size(), replaceOut);
            pos = pos2 + replaceOut.size();
        }
        else
            break;
    }
    return in;
}

如果您的项目设置为 unicode 字符(默认设置)- 到处使用 unicode 并使用 CF_UNICODETEXT 而不是 CF_TEXT。或者使用非 unicode - 但始终如一 - 然后更改项目设置。 下面的代码将正确地复制带有行尾的文本——在这个程序结束后,可以从记事本中粘贴由这个程序文本(带有行尾)复制的剪贴板:

#include <Windows.h>

BOOL WINAPI ToClipboard(VOID);

int main()
{
    ToClipboard();
}

BOOL WINAPI ToClipboard(VOID)
{
  LPTSTR  lptstrCopy;
  HGLOBAL hglbCopy;

  if (!OpenClipboard(NULL))
      return FALSE;
  EmptyClipboard();

  // Allocate a global memory object for the text. 
  wchar_t s[] = L"12345\n6789";
  hglbCopy = GlobalAlloc(GMEM_MOVEABLE,
      (wcslen(s) + 1) * sizeof(wchar_t));
  if (hglbCopy == NULL)
  {
      CloseClipboard();
      return FALSE;
  }

  lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);
  memcpy(lptstrCopy, &s,
    (wcslen(s) + 1) * sizeof(wchar_t));
  lptstrCopy[sizeof(s)] = (TCHAR)0;    // null character 
  GlobalUnlock(hglbCopy);

  SetClipboardData(CF_UNICODETEXT, hglbCopy);

  CloseClipboard();

  return TRUE;
}