关于剪贴板你需要知道的一切...






4.20/5 (44投票s)
1999年11月23日
2分钟阅读

416884

5858
本文将告诉你关于剪贴板你需要知道的一切...
引言
将剪贴板支持添加到 VC++ / MFC 应用程序非常简单。本文涵盖了让你的应用程序与剪贴板交互的基本步骤。其中包含以下示例:
读取和写入文本
以下源代码演示了如何将文本(包含在 CString
"source" 中)放置到剪贴板上。
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();
}
下面的源代码演示了相反的操作,即如何从剪贴板检索文本。
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();
}
读取和写入 WMF(增强)数据
将图像写入和从剪贴板读取可以非常有用,而且非常容易!以下示例将增强型元文件写入剪贴板。
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;
}
这是相反的操作。我们从剪贴板获取元文件并将其绘制到我们自己的客户端 DC 中(只是一个测试,实际上你想要创建一个副本)。
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();
}
读取和写入位图
读取和写入位图只是稍微复杂一些。基本思路仍然相同。这是一个将位图保存到剪贴板的示例。
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;
}
与其它示例一样,这是一个从剪贴板获取位图的示例。在这个简单的示例中,我们将直接将其 Blt 到客户端 DC。
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();
}
设置和使用你自己的自定义格式
通过使用 RegisterClipboardFormat()
API,你可以复制和粘贴任何类型的数据。这在应用程序之间移动数据时非常有用。假设我们有一个结构
struct MyFormatData
{
long val1;
int val2;
};
我们想将其移动到剪贴板上。我们可以按如下方式复制:
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();
}
要将其读回,我们执行相反的操作:
//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();
}
获取剪贴板更改的通知
每当剪贴板发生更改时,通过窗口消息获得通知非常有用。为此,你使用 SetClipboardViewer()
,然后捕获 WM_DRAWCLIPBOARD
。
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();
}
将数据粘贴到另一个应用程序的窗口
我发现的一个有用的事情是将文本复制到剪贴板(如上所述),然后将其“粘贴”到另一个应用程序!我编写了一个不错的本地化应用程序,它使用第三方语言翻译包使用了这种技术。
只需获取目标窗口的句柄并向其发送“粘贴”消息即可。
SendMessage(m_hTextWnd, WM_PASTE, 0, 0);
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。