分享
 
 
 

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

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Clipboard 问答集 1999.11.23 [Beginner] 平台: VC5, NT4 SP5

By Randy More

翻译:陈贵敏(efoxxx)

声明:此译文仅供网友们学习之用!您可以随意转载此译文,希望您转载时保留作译者和此声明。如有翻译不当之处,敬请指正: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);

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有