Click here to Skip to main content
15,867,835 members
Articles / Programming Languages / C++

All You Ever Wanted to Know About the Clipboard...

Rate me:
Please Sign up or sign in to vote.
4.19/5 (46 votes)
22 Nov 19992 min read 409.2K   5.8K   144   47
This article will tell you all that you ever wanted to know about the Clipboard...

Introduction

Adding clipboard support to a VC++ / MFC application is extremely simple. This article covers the basic steps involved in getting your applications talking to the clipboard. In it are examples of the following:

Reading and Writing Text

The following source code demonstrates how to place text (contained in the CString "source") onto the clipboard.

C++
CString source; 
//put your text in source
if(OpenClipboard())
{
	HGLOBAL clipbuffer;
	char * buffer;
	EmptyClipboard();
	clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength()+1);
	buffer = (char*)GlobalLock(clipbuffer);
	strcpy(buffer, LPCSTR(source));
	GlobalUnlock(clipbuffer);
	SetClipboardData(CF_TEXT,clipbuffer);
	CloseClipboard();
}

The source code below demonstrates the converse, how to retrieve text from the clipboard.

C++
char * buffer = NULL;
//open the clipboard
CString fromClipboard;
if ( OpenClipboard() ) 
{
	HANDLE hData = GetClipboardData( CF_TEXT );
	char * buffer = (char*)GlobalLock( hData );
	fromClipboard = buffer;
	GlobalUnlock( hData );
	CloseClipboard();
}

Reading and Writing WMF (Enhanced) Data

Writing and reading images to and from the clipboard can be very useful, and it is really very easy! The following example writes an enhanced metafile to the clipboard.

C++
if ( OpenClipboard() )
{
	EmptyClipboard();

	//create the metafile DC
	CMetaFileDC * cDC = new CMetaFileDC();
	cDC->CreateEnhanced(GetDC(),NULL,NULL,"the_name");

	//call draw routine here that makes GDI calls int cDC

	//close meta CMetafileDC and get its handle
	HENHMETAFILE handle = cDC->CloseEnhanced();

	//place it on the clipboard
	SetClipboardData(CF_ENHMETAFILE,handle);
	CloseClipboard();

	//delete the dc
	delete cDC;
}

Here is the converse. We get the metafile from the clipboard and draw it into our own client DC (just as a test, really you would want to make a copy).

C++
if ( OpenClipboard() )
{
	//Get the clipboard data
	HENHMETAFILE handle = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE);

	//play it into a DC (our own DC in this example)
	CClientDC dc(this);
	CRect client(0,0,200,200);
	dc.PlayMetaFile(handle,client);		

	//close the clipboard
	CloseClipboard();
}

Reading and Writing a Bitmap

Reading and writing a bitmap is only marginally trickier. The basic idea remains the same. Here is an example of saving a bitmap to the clipboard.

C++
if ( OpenClipboard() )
{
	EmptyClipboard();
	//create some data
	CBitmap * junk = new CBitmap();
	CClientDC cdc(this);
	CDC dc;
	dc.CreateCompatibleDC(&cdc);
	CRect client(0,0,200,200);
	junk->CreateCompatibleBitmap(&cdc,client.Width(),client.Height());
	dc.SelectObject(junk);

	//call draw routine here that makes GDI calls
	DrawImage(&dc,CString("Bitmap"));

	//put the data on the clipboard
	SetClipboardData(CF_BITMAP,junk->m_hObject);
	CloseClipboard();

	//copy has been made on clipboard so we can delete
	delete junk;
}

As with the other examples, here is an example of getting a bitmap from the clipboard. In this simple example, we will just Blt it to the client DC.

C++
if ( OpenClipboard() )
{
	//Get the clipboard data
	HBITMAP handle = (HBITMAP)GetClipboardData(CF_BITMAP);
	CBitmap * bm = CBitmap::FromHandle(handle);

	CClientDC cdc(this);
	CDC dc;
	dc.CreateCompatibleDC(&cdc);
	dc.SelectObject(bm);
	cdc.BitBlt(0,0,200,200,&dc,0,0,SRCCOPY);

	CloseClipboard();
}

Setting Up and Using Your Own Custom Format

By using the RegisterClipboardFormat() API, you can copy and paste any type of data you want. This can be very useful in moving data between your own applications. Let's say we have a structure:

C++
struct MyFormatData
{
	long val1;
	int val2;
};

that we want to move on the clipboard. We can copy as follows:

C++
UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
if(OpenClipboard())
{
	//make some dummy data
	MyFormatData data;
	data.val1 = 100;
	data.val2 = 200;

	//allocate some global memory
	HGLOBAL clipbuffer;
	EmptyClipboard();
	clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(MyFormatData));
	MyFormatData * buffer = (MyFormatData*)GlobalLock(clipbuffer);

	//put the data into that memory
	*buffer = data;

	//Put it on the clipboard
	GlobalUnlock(clipbuffer);
	SetClipboardData(format,clipbuffer);
	CloseClipboard();
}

To read it back off, we do the inverse:

C++
//second call with just get format already registered
UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
MyFormatData data;
if ( OpenClipboard() ) 
{
	//get the buffer
	HANDLE hData = GetClipboardData(format);
	MyFormatData * buffer = (MyFormatData *)GlobalLock( hData );

	//make a local copy
	data = *buffer;

	GlobalUnlock( hData );
	CloseClipboard();
}

Getting Notified of Clipboard Changes

It is very useful to be notified (via a windows message) whenever the clipboard has changed. To do this, you use SetClipboardViewer() and then catch WM_DRAWCLIPBOARD.

C++
In your initialization code call:
	SetClipboardViewer();  //add us to clipboard change notification chain

In your message map add:
	ON_MESSAGE(WM_DRAWCLIPBOARD, OnClipChange)  //clipboard change notification

Which is declared as:
	afx_msg void OnClipChange();  //clipboard change notification

Finally implement:
void CDetectClipboardChangeDlg::OnClipChange() 
{
	//do something here, for example
	CTime time = CTime::GetCurrentTime();
	SetDlgItemText(IDC_CHANGED_DATE,time.Format("%a, %b %d, %Y -- %H:%M:%S"));

	DisplayClipboardText();
}

Pasting Data to Another App's Window

One thing that I have found useful is to copy text to the clipboard (see above) and then to "paste" it to ANOTHER application!. I wrote a nice localization app that used a third party language translation package using this technique.

Simply get the handle to the target window and send a "PASTE" to it.

C++
SendMessage(m_hTextWnd, WM_PASTE, 0, 0);

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionPasting data of clipboard to Other Window by WINDOW TITLE and doing String manupulation like <=,== Text Pin
AdminSam18-Jan-12 20:30
AdminSam18-Jan-12 20:30 
GeneralMy vote of 4 Pin
AdminSam18-Jan-12 20:21
AdminSam18-Jan-12 20:21 
GeneralMy vote of 2 Pin
gordon885-Dec-11 17:36
professionalgordon885-Dec-11 17:36 
GeneralNEVER do this!!! PinPopular
John Crenshaw12-Jun-09 13:05
John Crenshaw12-Jun-09 13:05 
Questioncompile error _UNICODE Pin
winchnet200516-Nov-08 14:33
winchnet200516-Nov-08 14:33 
AnswerRe: compile error _UNICODE Pin
VEMS28-Jan-09 4:26
VEMS28-Jan-09 4:26 
AnswerRe: compile error _UNICODE Pin
AdminSam18-Jan-12 20:24
AdminSam18-Jan-12 20:24 
QuestionHow can manage all of copy and paste in system in C++ -&gt;please help me Pin
crackgns13-Aug-08 2:08
crackgns13-Aug-08 2:08 
I want to Know how can get the directory of file that copied in memory and I whant to know where copied file paseted
please help me!!
AnswerRe: How can manage all of copy and paste in system in C++ -&gt;please help me Pin
bukanr1co17-Jan-09 19:21
bukanr1co17-Jan-09 19:21 
QuestionHow to paste to a WORD app's window? Pin
test_15509-Sep-07 2:34
test_15509-Sep-07 2:34 
QuestionHow to get the XML data present in the Clipboard??? Pin
gloriousgopi15-Feb-07 3:17
gloriousgopi15-Feb-07 3:17 
Questionhow to capture a big window? Pin
Rockone8-Jan-07 2:42
Rockone8-Jan-07 2:42 
GeneralClipboard Query. Pin
HakunaMatada3-Aug-06 1:40
HakunaMatada3-Aug-06 1:40 
GeneralRe: Clipboard Query. Pin
Ashutosh Bhawasinka12-Dec-06 8:40
Ashutosh Bhawasinka12-Dec-06 8:40 
GeneralRe: Clipboard Query. Pin
marjaan27-Sep-07 20:14
marjaan27-Sep-07 20:14 
Generalcrash with release edition Pin
chinabcb16330-Jul-06 0:40
chinabcb16330-Jul-06 0:40 
GeneralRe: crash with release edition Pin
xox_c0bra_xox7-Sep-09 13:31
xox_c0bra_xox7-Sep-09 13:31 
GeneralMemory Leak [modified] Pin
Little.Ben26-Jul-06 1:31
Little.Ben26-Jul-06 1:31 
QuestionRe: Memory Leak Pin
PistolPeet9-May-07 7:01
PistolPeet9-May-07 7:01 
AnswerRe: Memory Leak (it's not a leak) Pin
dagronf27-Jun-07 17:11
dagronf27-Jun-07 17:11 
GeneralRe: Memory Leak (it's not a leak) Pin
PistolPeet27-Jun-07 23:19
PistolPeet27-Jun-07 23:19 
QuestionHow OnPaintClipboard() do ? Pin
trauconnguyen16-Apr-05 15:43
trauconnguyen16-Apr-05 15:43 
GeneralGetting a bitmap Pin
tunerica22-Jul-04 18:45
tunerica22-Jul-04 18:45 
GeneralPlease REJECT this article Pin
Anonymous22-May-03 9:48
Anonymous22-May-03 9:48 
GeneralRe: Please REJECT this article Pin
mathboy26-Jan-04 10:26
mathboy26-Jan-04 10:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.