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

1.2k views Asked by At

I'm developing some software which copies a large string to the windows clipboard to paste into some other software. Pasting in the other software does not work, and when I paste into Notepad, the newlines in the initial strings are gone, which is why it is failing to paste in the other software. I know this because when I re-add the newlines to Notepad, and do a Copy, Pasting then works in the other program. When I paste into Wordpad, the newlines are there mysteriously.

I'm using SetClipboardData() in C++ with the CF_TEXT clipboard format type. I've tried using CF_OEMTEXT, CF_DSPTEXT but neither of those work. I saw some documentation on CF_SYLK (Symbolic Link) for spreadsheets, as the software I'm pasting in is similar to a spreadsheet, but I couldn't get that to work either. Below is my code for copying to the clipboard.

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);

}

Any help is appreciated.

2

There are 2 answers

2
sppmacd On BEST ANSWER

The excel_str must have the CRLF line endings. Here is example code to convert string to the good format:

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;
}
1
AudioBubble On

If your project setup for unicode characters (default setup) - use unicode everywhere and use CF_UNICODETEXT instead CF_TEXT. Or use non unicode - but consistently - and then change project settings. Code below will copy text with line endings correctly - after end of this program it's possible to paste copied by this program text (with line endings) from clipboard from say notepad:

#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;
}