剪贴板大观园(三): Clipboard 问答集 (转)

本文详细介绍了如何在VC++/MFC应用程序中实现剪贴板的基本操作,包括文本、位图及自定义格式数据的拷贝与粘贴,并提供了获取剪贴板变化通知的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

剪贴板大观园(三): Clipboard 问答集 (转)[@more@] 

Clipboard 问答集  1999.11.23   [Beginner]   平台: VC5, NT4 SP5XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

By Mailto:rmore@cri.com">Randy More

翻译:陈贵敏(efoxxx)

 

声明:此译文仅供网友们学习之用!您可以随意转载此译文,希望您转载时保留作译者和此声明。如有翻译不当之处,敬请指正:.NET">mailto:efoxxx@263.net。近期,我会在《剪贴板大观园》系列中补充大量新的文章,希望与您交流,共同提高!

在我们自己的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(enhanced)数据

 

你想在你的程序中往剪贴板上“画”以及向剪贴板读取图形吗?请放心,这个――不难!示范代码如下,其实现的是往剪贴板上写一enhanced metafile。

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;

 
 

}

 
 

 

好啦,该演示反过来怎么做的代码了。我们从剪贴板上取得metafile并将其画到自己的应用程序的客户区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();

 
 

}

 
 

拷贝与粘贴一张位图(BitMap)

 

拷贝和粘贴位图可是需要一些微妙的处理的,不过基本的思想还是一样。请看下面的代码。

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;

 
 

}

 
 

 

 
 

如下示例代码是从剪贴板上取得一张位图,将它粘贴到客户区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();

 
 

}

 
 

 

想把它从剪贴板上读下来的话,也容易:

 

//第二次调用时,此格式已经注册过了,读下来就行了

 
 

UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");

 
 

MyFormatData data;

 
 

if ( OpenClipboard() )

 
 

{

 
 

  //get the buffer

 
 

  HANDLE hData = GetClipboardData(format);

 
 

  MyFormatData * buffer = (MyFormatData *)GlobalLock( hData );

 
 

 

 
 

  //留一份儿当地拷贝

 
 

  data = *buffer;

 
 

 

 
 

  GlobalUnlock( hData );

 
 

  CloseClipboard();

 
 

}

 
 

 


 

取得剪贴板变化通知(Getting notified of clipboard changes)

 

一旦剪贴板上的内容发生改变,我们都希望能够获知(经由windows消息),这是很有用的。你可以用函数SetClipboardViewer()来捕获WM_DRAWCLIPBOARD消息。

 

 
 

在你的初始化代码中调用:

 
 

  SetClipboardViewer();  //add us to clipboard change notification chain

 
 

 

 
 

在你的消息映射(message map)中添加:

 
 

  ON_MESSAGE(WM_DRAWCLIPBOARD, OnClipChange)  //clipboard change notification

 
 

 

 
 

将其定义为:

 
 

  afx_msg void OnClipChange();  //clipboard change notification

 
 

 

 
 

实现为:

 
 

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

 
 

}

 
 

 

将数据粘贴到其它应用程序窗口中的方法

 

我觉得如果能把文本拷贝到剪贴板上(参见上面的代码),然后再在另外一个应用程序中将这些文本粘贴过来,那样才有用。我写了一个很不错的本地应用程序,此程序使用了含有此技术的第三方的语言翻译包。很简单,仅是取得目标窗口的句柄,并向它发送“PASTE”消息就OK了。

  SendMessage(m_hTextWnd, WM_PASTE, 0, 0);


 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-991442/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-991442/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值