How to copy string to clipboard in C?
Solution 1
Read the MSDN documentation for the SetClipboardData function. It appears you are missing a few steps and releasing the memory prematurely. First of all, you must call OpenClipboard before you can use SetClipboardData. Secondly, the system takes ownership of the memory passed to the clipboard and it must be unlocked. Also, the memory must be movable, which requires the GMEM_MOVEABLE flag as used with GlobalAlloc (instead of LocalAlloc).
const char* output = "Test";
const size_t len = strlen(output) + 1;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, len);
memcpy(GlobalLock(hMem), output, len);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
Solution 2
I wrote an open source command line tool to do this in Windows:
http://coffeeghost.net/2008/07/25/ccwdexe-copy-current-working-directory-command/
ccwd.exe copies the current working directory to the clipboard. It's handy when I'm several levels deep into a source repo and need to copy the path.
Here's the complete source:
#include "stdafx.h"
#include "windows.h"
#include "string.h"
#include <direct.h>
int main()
{
LPWSTR cwdBuffer;
// Get the current working directory:
if( (cwdBuffer = _wgetcwd( NULL, 0 )) == NULL )
return 1;
DWORD len = wcslen(cwdBuffer);
HGLOBAL hdst;
LPWSTR dst;
// Allocate string for cwd
hdst = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (len + 1) * sizeof(WCHAR));
dst = (LPWSTR)GlobalLock(hdst);
memcpy(dst, cwdBuffer, len * sizeof(WCHAR));
dst[len] = 0;
GlobalUnlock(hdst);
// Set clipboard data
if (!OpenClipboard(NULL)) return GetLastError();
EmptyClipboard();
if (!SetClipboardData(CF_UNICODETEXT, hdst)) return GetLastError();
CloseClipboard();
free(cwdBuffer);
return 0;
}
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on June 03, 2020Comments
-
Admin about 4 years
The
SetClipboardData
function requires aHANDLE
reference; I'm having trouble converting my string for use in the function.Here is my code:
char* output = "Test"; HLOCAL hMem = LocalAlloc( LHND,1024); char* cptr = (char*) LocalLock(hMem); memcpy( cptr, output, 500 ); SetClipboardData(CF_TEXT, hMem); LocalUnlock( hMem ); LocalFree( hMem ); CloseClipboard();
What am I doing wrong here and what's the proper way to do it?
Thanks.
-
Admin almost 15 yearsWell, I've already looked at that, and came up with the code which doesn't work.
-
vishwas kumar almost 15 yearsYou might just try copying the exact code and see if it works. Then you can go from there.
-
Harvey about 12 yearsWorks for me too... with two corrections: GMEM_MOVEABLE and no parameter passed in OpenClipboard();
-
Jack about 10 yearsWhy copy the null-byte-terminattor too?
-
Elkvis almost 10 yearsbecause SetClipboardData doesn't accept a length parameter, so it has to figure out where the end of the string is, when you use CF_TEXT. See msdn.microsoft.com/en-us/library/windows/desktop/… for more info
-
Pyjong about 9 yearsDo I understand correctly, if the call to SetClipboardData succeeds system calls free(hMem) for you?
-
Yakov Galka over 7 years@Pyjong: Yes, except that it's
GlobalFree
. -
MultiplyByZer0 over 5 yearsNote that if you are copying a
wchar_t*
instead of achar*
, useCF_UNICODETEXT
instead ofCF_TEXT
. -
Berkyjay over 5 yearsAccoring to the documentation, this answer is wrong. You must pass a valid
HWND
toOpenClipboard
. Quote: "If an application calls OpenClipboard with hwnd set to NULL, EmptyClipboard sets the clipboard owner to NULL; this causes SetClipboardData to fail" -
Jan Bergström over 5 years+1 Yes, it is simple to read, copy and it works right on, just what I was looking for. And the CF_UNICODETEXT is a horror not getting. CF_TEXT makes only one letter in normal US ASCII. The DWORD len should be a size_t len (not getting compiler complaints).
-
Y K about 2 yearsThis doesn't work as @GetFree said.