Download clipboard demo project
- 12 Kb
Download notification demo project - 12 Kb
Adding clipboard support to a VC++ / MFC application is
extremely simple. This article covers the
basic steps involved in getting your applictions 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.
CString 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.
char * buffer = NULL;
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.
if ( OpenClipboard() )
{
EmptyClipboard();
CMetaFileDC * cDC = new CMetaFileDC();
cDC->CreateEnhanced(GetDC(),NULL,NULL,"the_name");
HENHMETAFILE handle = cDC->CloseEnhanced();
SetClipboardData(CF_ENHMETAFILE,handle);
CloseClipboard();
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).
if ( OpenClipboard() )
{
HENHMETAFILE handle = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE);
CClientDC dc(this);
CRect client(0,0,200,200);
dc.PlayMetaFile(handle,client);
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.
if ( OpenClipboard() )
{
EmptyClipboard();
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);
DrawImage(&dc,CString("Bitmap"));
SetClipboardData(CF_BITMAP,junk->m_hObject);
CloseClipboard();
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 cleint DC.
if ( OpenClipboard() )
{
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:
struct MyFormatData
{
long val1;
int val2;
};
that we want to move on the clipboard. We can copy as follows:
UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
if(OpenClipboard())
{
MyFormatData data;
data.val1 = 100;
data.val2 = 200;
HGLOBAL clipbuffer;
EmptyClipboard();
clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(MyFormatData));
MyFormatData * buffer = (MyFormatData*)GlobalLock(clipbuffer);
*buffer = data;
GlobalUnlock(clipbuffer);
SetClipboardData(format,clipbuffer);
CloseClipboard();
}
To read it back off we do the inverse:
UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
MyFormatData data;
if ( OpenClipboard() )
{
HANDLE hData = GetClipboardData(format);
MyFormatData * buffer = (MyFormatData *)GlobalLock( hData );
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
In your initialization code call:
SetClipboardViewer();
In your message map add:
ON_MESSAGE(WM_DRAWCLIPBOARD, OnClipChange)
Which is declared as:
afx_msg void OnClipChange();
Finally implement:
void CDetectClipboardChangeDlg::OnClipChange()
{
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.
SendMessage(m_hTextWnd, WM_PASTE, 0, 0);
| You must Sign In to use this message board. |
|
|
 |
|
 |
"One thing that I have found useful is to copy text to the clipboard (see above) and then to "paste" it to ANOTHER application!"
To anyone who has ever considered such a hack, the rule on this is NEVER EVER EVER EVER EVER!!!     The clipboard belongs to the user, not the program you are writing. Under no circumstances should you ever write to the clipboard unless the user is expecting to be able to paste what you added.
Storing the old value in temp and putting it back on the clipboard is also not acceptable, since some users use clipboard managers to maintain a history of clips.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
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!!
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
Hello Sir,
Nice article and i could able to learn some new things from it. and i got a problem while coding for a module. could you please help me.
The problem is :
I copied some xml contents(Data) into the clipboard by selecting the XML contents and copying them using CTRL+C. But when i am accessing it through the fuction GetClipboardData(CF_TEXT), i couldn't able to get the data. Even though the data present in it is in Text format.
Could you please explain, why its happening like that and if there is any other solution to over come this problem.
Thanks for your help in advance.
From
Gopinath MV
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
i want to capture a window to the clipboard. when the document size is bigger than current viewable rectangle, the captured image will has a big black block.
Can anyone give me some help or tips?
Thank you in advance.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
In Office 2003, the inbuilt clipboard viewer shows all the data that has been copied to the clipboard. My question is, Is the Clipboard capable of handling multiple "CTRL+C"s? I mean if I copy some text then I copy another set of text, will the previous one be overwritten or will it remain in the clipboard at a different index( like in an array )?
My situation is such that I want to use the clipboard but not lose the previous data which was there. i.e. After my work with the clipboard is done, it should be set with the previous data which was there, irrespective of the type of data. How do I achieve it?
---  Hakuna-Matada It means no worries for the rest of your days... It's our problem free, Philosophy<marquee behavior=alternate scrollamount=5 scrolldelay=50>  </marquee>
|
| Sign In·View Thread·PermaLink | 4.00/5 |
|
|
|
 |
|
 |
no. the clipboard is not capable of handling multiple data.
In office 2003, its maintained by office itself. If you copy something from office application, only the last copied data is available outside the office application.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
It's possible that u store the former contents of clipboard in some temporary variable, then use it for your current purpose and then restore it to the original contents.......
~Gaasha~
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
when I try to call the SetClipboardViewer() function it crashes my application (application error). Why does it do this? Any ideas?
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hello,
Well lets see maybe if you open the clipboard first and check the return value is sucessfull before calling the other functions maybe it will work, because oviously your not setting up properly if this crashes your application.
Liquid Snake
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thank you for the code to transfer data to/from the clipboard. I have used the parts concerning text transfer, they are doing their job very well.
But I have found one thing: The methode for retrieving text from the clipboard looses memory (Chapter "Reading and Writing Text"). Call GlobalFree(clipbuffer); at the end and it will be fixed 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I followed another tutorial that did include the GlobalFree call, however I'm finding that I'm getting heap corruption while freeing the memory. I'm sure the buffer isn't overflowing (unless a char in the global alloc is a different size than sizeof(char)?).
Are you experiencing the same heap corruption? How can I get around this without leaving the memory allocated?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
You don't delete the memory in clipbuffer -- the online help for SetClipboardData states :-
"After SetClipboardData is called, the system owns the object identified by the hMem parameter. The application can read the data, but must not free the handle"
So, don't delete it. The system will clean it up as required.
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|
 |
|
 |
How The Owner Clipboard process OnPaintClipboard() (from message WM_PAINTCLIPBOARD)? Fuction GlobalAlloc(hMem) return handle of memory has Alloced and int* p = GlobalLock(hMem) return pointer to address of memory Ask : p == hMem (TRUE or FALSE ?) When p==hMem ?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I have tried to use this article and the infromation that it provides to retrieve a bitmap from the clipboard, and it doesn't seem to be working. When I run the debugger it seem that this call is the one that is not working:
HBITMAP handle = (HBITMAP)GetClipboardData(CF_BITMAP);
The debugger has the following listed for handle:
CXX0030: Error: Expression can not be evaluated.
Why is this? What has gone wrong? If anything, cause I may just not understand it.
Micheal
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
 |
As the programmer of a popular Clipboard Monitor, it's garbage like this that makes my life hell. It's dead wrong and does NOT follow the Microsoft Documentation. As mentioned above, it breaks the clipboard chain and effectively breaks any and all monitors.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/dataexchange/clipboard/clipboardreference/clipboardmessages/wm_changecbchain.asp
|
| Sign In·View Thread·PermaLink | 2.33/5 |
|
|
|
 |
|
 |
Aren't you referring to a single but important missing line, trivially added, as stated in a previous comment?
Isn't it obvious that it would be much better to fix the article, helping readers to use the correct method, than reject it? It looks like a useful well written article to me, apart from that one easily addressed issue. It's a shame you couldn't be more constructive ;o)
|
| Sign In·View Thread·PermaLink | 3.00/5 |
|
|
|
 |
|
|
 |
|
 |
Hello,
There isnt anything wrong with this article, Everything the dude posted works just fine, I mean come on if you people cant get whats in this article to work maybe you better learn Visual C++ and stop downing the data in this article.
Liquid Snake
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hello,
There isnt anything wrong with this article, Everything the dude posted works just fine, I mean come on if you people cant get whats in this article to work maybe you better learn Visual C++ and stop downing the data in this article.
I dont see any of your code up in here MR Clipboard Monitor Programmer posted as anonymous because your stupid..
Liquid Snake
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am actually a foxpro guy, I want to extract the image from general field of foxpro which is currupt. I have collected the info that this field stores the preview of image and Image also when the image is embeded. I found the a word METAFILEPICT in that field. I don't know C language but i can use the foxpro low level language by that i want to read the preview and copy to it in image file as i know that preview is device independent. can any body help me to this.
Regards Anirudhas
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
|