分享
 
 
 

剪贴板大观园(二): 剪贴板间谍(ClipSpy)

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

ClipSpy

1999.12.27 [beginner] 作者:Michael Dunn

翻译:陈贵敏(efoxxx)

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

描述:一个观察剪贴板和即拖即存数据的工具。 要求平台:VC6; Win 98/2000, Unicode

图1:ClipSpy展示了Word 97中简单的copy操作后被贴到剪贴板上的数据

图2:ClipSpy展示了Word中即拖即存所生成的数据

简介

最近有些空闲时间,我一直在思考Windows编程中一个我一直想知道却不知道的领域,也就是剪贴板。

我已经自己写了一个处理剪贴板上文件拖放(HDROP) 数据的工具,用它来仿真Explorer(资源管理器)的拷贝和粘贴命令,可是呢,仅仅能拷贝粘贴一种数据格式是远远不够的。我想更深入地考察一下剪贴板上的内容,通过这个过程说不准儿我会找到一些关于应用程序中使用剪贴板的一些技巧性的东西。(举个例子,什么是“Woozle”?――见上边图2左边的列表框。)

好啦,这一段空闲时间已经到了最后的周末了(我已把圣诞节要买的东西都买好了,真是太妙了),而且这个阶段的自学的最终结局是“ClipSpy”,一个马力增强了的剪贴板观察器。 另外,它还可以观察到即拖即存操作中的数据(因为MFC使用同一个类来处理即拖即存和剪贴板),不过,我还是叫它ClipSpy ,因为ClipboardAndDragAndDropSpy敲起来确实有点儿费劲儿。

如果您急切地想知道更多有关clipboard的知识,请直接跳到“实现细节”部分,这里我会专门指出代码中的值得一看的地方。

ClipSpy是用MSVC 6, SP2所写。我分别在 Windows 98 和 Windows 2000 build 2072(both ANSI and Unicode builds )作了测试。

ClipSpy 做了些什么

ClipSpy将自己注册为一个剪贴板观察器,这一部分其实没有什么神秘的。 可就在剪贴板上的内容发生变化的同时,ClipSpy 枚举出所有在剪贴板上的数据格式(剪贴板上的数据格式可能有很多种)并且将它们显示在左侧的面板中。 在格式列表中选择一种格式并单击鼠标左键,就会在右侧的面板中显示放在剪贴板上的数据。右侧面板的功能有点儿象MSVC的内存debug窗口,它不仅有ASCII代码,还有原始数据。

左侧的面板亦可做为拖放操作的目标来用,也就是说你可以从一个支持拖放的程序中把任何格式的数据拖到此列表中来,ClipSpy会显示出全部拖过来的数据。跟前边说一样,各种数据格式列于左侧的面板中,单击任一种格式的数据ClipSpy都会将相应的数据显示在右边的面板中。

File菜单下也有一对相应的菜单命令。“Read Clipboard”命令为重新读取剪贴板上的内容,你可以在执行了拖放操作之后使用此命令来再显示以下剪贴板上的内容。 “Empty Clipboard”命令会让你的剪贴板空空如也。

实现细节

ClipSpy的大多数工作都是通过MFC类COleDataObject完成的,此COleDataObject实现了接口IdataObject,并且提供了访问剪贴板上的数据以及拖放的数据源的方法。成员函数CLeftView::ReadDataAndFillList()是用来枚举剪贴板上的数据格式并将其写到列表(list)控件中。枚举代码如下所示:

BOOL CLeftView::ReadDataAndFillList ( COleDataObject* pDO )

{

FORMATETC etc;

UINT uNumFormats = 0; //.剪贴板上数据格式种类数

pDO->BeginEnumFormats();

while ( pDO->GetNextFormat ( &etc ))

{

if ( pDO->IsDataAvailable ( etc.cfFormat ))

{

uNumFormats++;

}

}

}

对于每一种格式,ClipSpy首先检查它是否是内建类型。如果不是的话,ClipSpy就会取得此格式的标记字符串,并调用函数GetClipboardFormatName():

TCHAR szFormat [256];

GetClipboardFormatName ( etc.cfFormat, szFormat, 256 );

ClipSpy有一用于内建类型的字符串列表(因为GetClipboardFormatName()函数只识别程序已注册过的基本类型)。然后,ClipSpy开始试着去读取此格式对应的数据:

HGLOBAL hgData;

UINT uDataSize;

CClipSpyDoc* pDoc = GetDocument();

// Get an HGLOBAL of the data.

hgData = pDO->GetGlobalData ( etc.cfFormat );

if ( NULL != hgData )

{

uDataSize = GlobalSize ( hgData );

pDoc->AddDataBlock ( hgData, uDataSize );

}

else

{

pDoc->AddEmptyBlock();

}

函数AddDataBlock()和AddEmptyBlock()都是文档类的成员函数。文档类则是存放所有数据的拷贝的场所。

当把数据拖到列表空间中时,也会执行一样的代码――成员函数CLeftView::OnDrop()中有一COleDataObject 对象,在调用ReadDataAndFillList()时直接将此对象作为参数传递过来。

其它你可能感兴趣的地方有CLeftView::OnItemchanged() 和 CClipSpyView::OnUpdate()。CLeftView::OnItemchanged()用于监测列表,当你更换了选中的Format项时,会触发此事件,并调用UpdateAllViews(),而UpdateAllViews()会依次调用OnUpdate()。OnUpdate()用于将数据写到RechEdit控件中去。

本程序存在的一些问题

在拖放操作之后,函数COleDataObject::GetGlobalData()有时会发生读取某些数据失败。由于在拖放这一技术上我也只是个新手,我还没有找到其原因(或者说是其解决方案)。呵呵,现在如果这一可怕的情况发生的话,ClipSpy只会列出其数据格式,而在“Data size”一栏中提示“<Data unavailable>”。

注意,程序的右边面板上放的是一个RichEdit控件,你可以从它那里拷贝东西到剪贴板上。可我必须告诉你,你不要对它进行拷贝,这样做会导致OLE内部冲突。再次声明:这个问题可能是由于我的代码自身的错误,您就不要用此功能好了。:)

由于剪贴板数据所占内存最初是由GlobalAlloc()函数分配的,所以每一块儿数据都比数据本身要长。(因为“字节对其(byte-alignment)”的原因,GlobalAlloc()会分配一块儿比你执行请求要大的内存)。比如说在Win98中,我用MSVC拷贝8个字符长的单词到剪贴板上,剪贴板上包含32字节的CF_TEXT(普通的ANSI文本)数据,其中前9个那个单词(8字节加上一个字符串结束符null),剩下的都是些乱糟糟的垃圾。ClipSpy把一整块儿的数据都显示出来,不作任何的解释处理。

对了,你一定要记住:如果你要debug这个程序――也就是说当你一步一步执行程序时,千万不要使用剪贴板。因为ClipSpy还没有完全运行起来,我可要祝贺你了,:)全部的剪贴板操作被挂起,ClipSpy、MSVC以及所有你曾在这一时间内使用剪贴板操作的程序都统统崩溃!妈呀,好像只有按Reset键重启爱机了。

请访问站点http://home.inreach.com/mdunn/code/,这里有相关的最新更新以及我的其它一些文章。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有