你想知道的关于剪贴板的一切…

介绍 在vc++ / MFC应用程序中添加剪贴板支持是非常简单的。本文介绍了让应用程序与剪贴板对话所涉及的基本步骤。其中有以下例子: 读取和写入文本读取和写入WMF数据读取和写入位图设置和使用自己的自定义格式得到通知剪贴板的变化粘贴数据到另一个应用程序的窗口 阅读和写作 下面的源代码演示了如何将文本(包含在CString“source”中)放到剪贴板上。 隐藏,复制Code

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();
}

下面的源代码演示了相反的方法,即如何从剪贴板检索文本。 隐藏,复制Code

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(增强)数据 从剪贴板写入和读取图像非常有用,而且它真的非常简单!下面的示例将一个增强的元文件写入剪贴板。 隐藏,复制Code

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中(只是作为测试,实际上您需要复制)。 隐藏,复制Code

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();
}

读取和写入位图 读取和写入位图只是稍微复杂一点。基本的想法是一样的。下面是一个将位图保存到剪贴板的例子。 隐藏,复制Code

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。 隐藏,复制Code

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,您可以复制和粘贴任何类型的数据。这在您自己的应用程序之间移动数据时非常有用。假设我们有一个结构: 隐藏,复制Code

struct MyFormatData
{
	long val1;
	int val2;
};

我们想要在剪贴板上移动它。我们可以复制如下: 隐藏,复制Code

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();
}

为了把它读出来,我们反过来做: 隐藏,复制Code

//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();
}

获得剪贴板更改的通知 当剪贴板发生更改时,得到通知(通过windows消息)是非常有用的。为此,您使用SetClipboardViewer(),然后捕捉WM_DRAWCLIPBOARD。 隐藏,复制Code

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();
}

将数据粘贴到另一个应用程序的窗口 我发现有用的一件事是复制文本到剪贴板(见上面),然后“粘贴”到另一个应用程序!我写了一个很好的本地化应用程序,它使用了使用这种技术的第三方语言翻译包。 只需获得目标窗口的句柄并发送一个“粘贴”到它。 隐藏,复制Code

SendMessage(m_hTextWnd, WM_PASTE, 0, 0);

许可证 本文没有附带明确的许可,但可能包含文章文本或下载文件本身的使用条款。如果有疑问,请通过下面的讨论区联系作者。 可以在这里找到作者可能使用的许可证列表。 本文转载于:http://www.diyabc.com/frontweb/news229.html

posted @ 2020-08-04 08:13  Dincat  阅读(336)  评论(0编辑  收藏  举报