|
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. |
|
| | Msgs 1 to 25 of 35 (Total in Forum: 35) (Refresh) | FirstPrevNext |
|
 |
|
|
 |
|
|
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 | |
|
|
|
 |
|
|
I have tried to use "SendMessage(m_TexthWnd,WM_PASTE,0,0)",but it doesn't work. How can I do?
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
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.13/5 (4 votes) |
|
|
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
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.00/5 (3 votes) |
|
|
|
 |
|
|
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.67/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
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 (1 vote) |
|
|
|
 |
|
|
1) WM_DRAWCLIPBOARD handler can be added with ClassWizard - just select "windows" message filter there.
2) Why you doesn't pass to the next clipboard viewer?
HINSTANCE hinst; UINT uFormat = (UINT)(-1); BOOL fAuto = TRUE; LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam) HWND hwnd; UINT uMsg; WPARAM wParam; LPARAM lParam; { static HWND hwndNextViewer; HDC hdc; HDC hdcMem; PAINTSTRUCT ps; LPPAINTSTRUCT lpps; RECT rc; LPRECT lprc; HGLOBAL hglb; LPSTR lpstr; HBITMAP hbm; HENHMETAFILE hemf; HWND hwndOwner; switch (uMsg) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); // Branch depending on the clipboard format. switch (uFormat) { case CF_OWNERDISPLAY: hwndOwner = GetClipboardOwner(); hglb = GlobalAlloc(GMEM_MOVEABLE, sizeof(PAINTSTRUCT)); lpps = GlobalLock(hglb); memcpy(lpps, &ps, sizeof(PAINTSTRUCT)); GlobalUnlock(hglb); SendMessage(hwndOwner, WM_PAINTCLIPBOARD, (WPARAM) hwnd, (LPARAM) hglb); GlobalFree(hglb); break; case CF_BITMAP: hdcMem = CreateCompatibleDC(hdc); if (hdcMem != NULL) { if (OpenClipboard(hwnd)) { hbm = (HBITMAP) GetClipboardData(uFormat); SelectObject(hdcMem, hbm); GetClientRect(hwnd, &rc); BitBlt(hdc, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY); CloseClipboard(); } DeleteDC(hdcMem); } break; case CF_TEXT: if (OpenClipboard(hwnd)) { hglb = GetClipboardData(uFormat); lpstr = GlobalLock(hglb); GetClientRect(hwnd, &rc); DrawText(hdc, lpstr, -1, &rc, DT_LEFT); GlobalUnlock(hglb); CloseClipboard(); } break; case CF_ENHMETAFILE: if (OpenClipboard(hwnd)) { hemf = GetClipboardData(uFormat); GetClientRect(hwnd, &rc); PlayEnhMetaFile(hdc, hemf, &rc); CloseClipboard(); } break; case 0: GetClientRect(hwnd, &rc); DrawText(hdc, "The clipboard is empty.", -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER); break; default: GetClientRect(hwnd, &rc); DrawText(hdc, "Unable to display format.", -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER); } EndPaint(hwnd, &ps); break; case WM_SIZE: if (uFormat == CF_OWNERDISPLAY) { hwndOwner = GetClipboardOwner(); hglb = GlobalAlloc(GMEM_MOVEABLE, sizeof(RECT)); lprc = GlobalLock(hglb); GetClientRect(hwnd, lprc); GlobalUnlock(hglb); SendMessage(hwndOwner, WM_SIZECLIPBOARD, (WPARAM) hwnd, (LPARAM) hglb); GlobalFree(hglb); } break; case WM_CREATE: // Add the window to the clipboard viewer chain. hwndNextViewer = SetClipboardViewer(hwnd); break; case WM_CHANGECBCHAIN: // If the next window is closing, repair the chain. if ((HWND) wParam == hwndNextViewer) hwndNextViewer = (HWND) lParam; // Otherwise, pass the message to the next link. else if (hwndNextViewer != NULL) SendMessage(hwndNextViewer, uMsg, wParam, lParam); break; case WM_DESTROY: ChangeClipboardChain(hwnd, hwndNextViewer); PostQuitMessage(0); break; case WM_DRAWCLIPBOARD: // clipboard contents changed. // Update the window by using Auto clipboard format. SetAutoView(hwnd); // Pass the message to the next window in clipboard // viewer chain. SendMessage(hwndNextViewer, uMsg, wParam, lParam); break; case WM_INITMENUPOPUP: if (!HIWORD(lParam)) InitMenu(hwnd, (HMENU) wParam); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_EXIT: DestroyWindow(hwnd); break; case IDM_AUTO: SetAutoView(hwnd); break; default: fAuto = FALSE; uFormat = LOWORD(wParam); InvalidateRect(hwnd, NULL, TRUE); } break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return (LRESULT) NULL; } void WINAPI SetAutoView(HWND hwnd) { static UINT auPriorityList[] = { CF_OWNERDISPLAY, CF_TEXT, CF_ENHMETAFILE, CF_BITMAP }; uFormat = GetPriorityClipboardFormat(auPriorityList, 4); fAuto = TRUE; InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } void WINAPI InitMenu(HWND hwnd, HMENU hmenu) { UINT uFormat; char szFormatName[80]; LPCSTR lpFormatName; UINT fuFlags; UINT idMenuItem; // If a menu is not the display menu, no initialization is necessary. if (GetMenuItemID(hmenu, 0) != IDM_AUTO) return; // Delete all menu items except the first. while (GetMenuItemCount(hmenu) > 1) DeleteMenu(hmenu, 1, MF_BYPOSITION); // Check or uncheck the Auto menu item. fuFlags = fAuto ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED; CheckMenuItem(hmenu, IDM_AUTO, fuFlags); // If there are no clipboard formats, return. if (CountClipboardFormats() == 0) return; // Open the clipboard. if (!OpenClipboard(hwnd)) return; // Add a separator and then a menu item for each format. AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); uFormat = EnumClipboardFormats(0); while (uFormat) { // Call an application-defined function to get the name // of the clipboard format. lpFormatName = GetPredefinedClipboardFormatName(uFormat); // For registered formats, get the registered name. if (lpFormatName == NULL) { if (GetClipboardFormatName(uFormat, szFormatName, sizeof(szFormatName))) lpFormatName = szFormatName; else lpFormatName = "(unknown)"; } // Add a menu item for the format. For displayable // formats, use the format ID for the menu ID. if (IsDisplayableFormat(uFormat)) { fuFlags = MF_STRING; idMenuItem = uFormat; } else { fuFlags = MF_STRING | MF_GRAYED; idMenuItem = 0; } AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName); uFormat = EnumClipboardFormats(uFormat); } CloseClipboard(); } BOOL WINAPI IsDisplayableFormat(UINT uFormat) { switch (uFormat) { case CF_OWNERDISPLAY: case CF_TEXT: case CF_ENHMETAFILE: case CF_BITMAP: return TRUE; } return FALSE; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
hi,
i have a process that needs to give its clipboard information (contents, size of contents) to another process on another machine. These 2 processes communicate via sockets. If the clipboard has data in text format, i am able to convert that to characters and send it across to receiving process. However, the problem comes when clipboard data is in CF_BITMAP form. How can i convert this into raw bytes and send it across using sockets?
Thanx,
|
| Sign In·View Thread·PermaLink | 2.67/5 (3 votes) |
|
|
|
 |
|
|
Error:error C2065: 'DrawImage' : undeclared identifier Error executing cl.exe.
Test.exe - 1 error(s), 0 warning(s)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Greetings, just wondering about file transfers using clipboard. My project requires me to transfer some pqa/prc (palm format) files from one application to another application through clipboard. Just wondering how I could adapt the above format to accomplish this.
Hopelessly loss
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi,
when I try to call the SetClipboardViewer() function it crashes my application (application error). Why does it do this? Any ideas?
/Daniel
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
I have problem when I try to copy the MetaFile from the clipboard. The step I done :-
- make drawing from MSword copy by Ctrl+C - make Ctrl+P in my project a try this code by "C" not in c++ hClip = (HENHMETAFILE )GetClipboardData(CF_ENHMETAFILE); //I set rr = client(0,0,200,200); uni = PlayEnhMetaFile(hDC,hClip ,&rr);
- but it not play the MetaFile when I use
short uni = GetEnhMetaFileBits(metap,uni,lpby); it show size of MetaFile but I cann't get pointer of MetaFile
How can I do for get the pointer and show the MetaFile and save it
And What is Defination of MetaFile or EnhMetaFile.
Thank you for your help Jane Monchai
Monchai
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|