天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 4|回复: 0

VC的剪贴板操作

[复制链接]
  • TA的每日心情
    开心
    昨天 06:36
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    105

    主题

    11

    回帖

    1308

    积分

    管理员

    积分
    1308
    QQ
    发表于 5 天前 | 显示全部楼层 |阅读模式
    1. VC的剪贴板操作



    2. 1、文本内容的操作
    3. 2、WMF数据的操作
    4. 3、位图的操作
    5. 4、设置使用自定义格式
    6. 5、感知剪贴板内容的改变
    7. 6、自动将数据粘贴到另一应用程序窗口

    8. 一、文本内容的操作
    9. 下面的代码示范了如何将文本内容复制到剪贴板(Unicode编码的先转化为ASCII):

    10. CString source;
    11. //文本内容保存在source变量中
    12. if( OpenClipboard() )
    13. {
    14. HGLOBAL clipbuffer;
    15. char * buffer;
    16. EmptyClipboard();
    17. clipbuffer = GlobalAlloc(GMEM_DDESHARE, source.GetLength()+1);
    18. buffer = (char*)GlobalLock(clipbuffer);
    19. strcpy(buffer, LPCSTR(source));
    20. GlobalUnlock(clipbuffer);
    21. SetClipboardData(CF_TEXT,clipbuffer);
    22. CloseClipboard();
    23. }

    24. 下面的代码显示了如何从剪贴板上获得文本内容:

    25. char * buffer = NULL;
    26. //打开剪贴板
    27. CString fromClipboard;
    28. if ( OpenClipboard() )
    29. {
    30. HANDLE hData = GetClipboardData(CF_TEXT);
    31. char * buffer = (char*)GlobalLock(hData);
    32. fromClipboard = buffer;
    33. GlobalUnlock(hData);
    34. CloseClipboard();
    35. }

    36. 二、WMF数据的操作

    37.   在剪贴板上读写图象数据是非常有用的功能,并且实现起来也很简单。下面的代码显示了如何将扩展图元文件复制到剪贴板:

    38. if(OpenClipboard());
    39. {
    40. EmptyClipboard();

    41. //创建图元文件DC
    42. CMetaFileDC * cDC = new CMetaFileDC();
    43. cDC->CreateEnhanced(GetDC(),NULL,NULL,"the_name");

    44. //调用绘图例程

    45. //关闭CMetafileDC并获得它的句柄
    46. HENHMETAFILE handle = cDC->CloseEnhanced();

    47. //复制到剪贴板
    48. SetClipBoardData(CF_ENHMETAFILE,handle);
    49. CloseClipboard();

    50. //删除dc
    51. delete cDC;
    52. }

    53. 下面的代码演示了从剪贴板获得图元文件并将其绘制到client DC上:

    54. if(OpenClipboard())
    55. {
    56. //获得剪贴板数据
    57. HENMETAFILE handle = (HENMETAFILE)GetClipboardData(CF_ENHMETAFILE);

    58. //显示
    59. CClientDC dc(this);
    60. CRect client(0,0,200,200);
    61. dc.PlayMetaFile(handle,client);

    62. //关闭剪贴板
    63. CloseClipboard();
    64. }
    65. 三、位图的操作


    66. 位图的操作稍微复杂一点,下面这个例子显示了如何在剪贴板保存位图:

    67. if(OpenClipboard())
    68. {
    69. EmptyClipboard();
    70. CBitmap * junk = new CBitmap();
    71. CClientDC cdc(this);
    72. CDC dc;
    73. dc.CreateCompatibleDC(&cdc);
    74. CRect client(0,0,200,200);
    75. junk->CreateCompatibleBitmap(&cdc,client.Width(),client.Height());
    76. dc.SelectObject(junk);

    77. DrawImage(&dc,CString("Bitmap"));

    78. //复制数据到剪贴板
    79. SetClipboardData(CF_BITMAP,junk->m_hObject);
    80. CloseClipboard();

    81. delete junk;
    82. }

    83. 下面的代码显示了如何从剪贴板上获得位图数据:

    84. if(OpenClipboard())
    85. {
    86. //获得剪贴板数据
    87. HBITMAP handle = (HBITMAP)GetClipboardData(CF_BITMAP);
    88. CBitmap * bm = CBitmap::FromHandle(handle);

    89. CClientDC cdc(this);
    90. CDC dc;
    91. dc.CreateCompatibleDC(&cdc);
    92. dc.SelectObject(bm);
    93. cdc.BitBlt(0,0,200,200,&dc,0,0,SRCCOPY);

    94. CloseClipboard();
    95. }

    96. 四、设置并使用自定义格式

    97. 使用RegisterClipboardFormat()函数,可以复制和粘贴任何你需要的数据类型。比如我们有以下一个数据类型:

    98. struct MyFormatData
    99. {
    100. long val1;
    101. int val2;
    102. };

    103. 我们要把它复制到剪贴板,可以使用如下的代码:

    104. UINT format = RegisterClipBoardFormat("MY_CUSTOM_FORMAT");
    105. if(OpenClipboard())
    106. {
    107. MyFormatData data;
    108. data.val1 = 100;
    109. data.val2 = 200;

    110. HGLOBAL clipbuffer;
    111. EmptyClipboard();
    112. clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(MyFormatData));
    113. MyFormatData * buffer = (MyFormatData*)GlobalLock(clipbuffer);

    114. //保存到内存
    115. *buffer = data;

    116. //保存到剪贴板
    117. GlobalUnlock(clipbuffer);
    118. SetClipboardData(format,clipbuffer);
    119. CloseClipboard();
    120. }

    121. 读取数据使用以下代码:

    122. UINT format = RegisterClipboardFormat("MY_CUSTOM_FORMAT");
    123. MyFormatData data;
    124. if(Openclipboard())
    125. {
    126. HANDLE hData =GetClipboardData(format);
    127. MyFormatData * buffer = (MyFormatData*)GlobalLock(hData);

    128. data = *buffer;

    129. GlobalUnlock(hData);
    130. CloseClipboard();
    131. }

    132. 五、感知剪贴板内容的改变

    133. 通过Windows消息可以感知剪贴板内容是否发生改变,代码如下:

    134. //In your initialization code call:

    135. SetClipboardViewer(); //将我们的程序添加到剪贴板观察链

    136. //In your message map add:
    137. ON_MESSAGE(WM_DRAWCLIPBOARD, OnClipChange) //添加Message handle

    138. //Which is declared as:

    139. afx_msg void OnClipChange();

    140. Finally implement:
    141. void CDetectClipboardChangeDlg::OnClipChange()
    142. {
    143. CTime time = CTime::GetCurrentTime();
    144. SetDlgItemText(IDC_CHANGED_DATE,time.Format("%a, %b %d, %Y -- %H:%M:%S"));

    145. DisplayClipboardText();
    146. }

    147. 六、自动将数据粘贴到另一应用程序窗口

    148. 只需获得相应窗口的句柄,并发送一个消息就可以了:

    149. SendMessage(m_hTextWnd, WM_PASTE, 0, 0);



    150. 传统Windows剪贴板编程


    151. 将数据复制到剪贴板:
    152. 1.调用OpenClipboard()设置数据的源窗口.
    153. 2.调用EmptyClipboard()清空剪贴板中以前的数据.
    154. 3.调用SetClipboardData()将数据存放到剪贴板上.
    155. 4.调用CloseClipboard()使别的窗口能访问剪贴板.
    156. 取得剪贴板上的数据:
    157. 1.调用OpenClipboard()访问剪贴板.
    158. 2.调用GetClipboardData()取得数据.
    159. 3.调用CloseClipboard()释放剪贴板.

    160. 使用延迟供应技术时,源数据方以NULL为数据句柄调用SetClipboardData(),数据使用方GetClipboardData()时,Windows向数据产生者发送WM_RENDERFORMAT和WM_RENDERFORMATS消息,数据提供者响应消息并产生数据.

    161. 局限性:使用全局内存来传输,数据量大时系统要使用虚拟内存管理机制来管理,对交换效率有很大影响.

    162. //------------------------------------------------------------
    163. OLE剪贴板

    164. 介于应用程序与标准剪贴板间,从标准剪贴板扩展而来,补充了OLE的数据传输机制,对标准剪贴板向后兼容.
    165. OLE剪贴板使用IDataObject接口进行传输,相关的API:
    166. .OleSetClipboard():在剪贴板上放置一个IDataObject接口指针.
    167. .OleGetClipboard():从剪贴板上取得一个IDataObject接口指针.
    168. .OleFlushClipboard():清空OLE剪贴板,释放上面的IDataObject接口指针.
    169. .OleIsCurrentClipboard():判断指定的对象当前是否在剪贴板上.
    170. OLE剪贴板的工作步骤:
    171. 1.数据创造者程序将数据放到剪贴板并实现IDataObject.数据创造者用OleSetClipboard()得IDataObject的一个拷贝.并将其放到剪贴板上.
    172. 2.剪贴板上有IDataObject指针时,OLE像普通应用程序一样使用剪贴板.OLE调用OpenClipboard来声明剪贴板的拥有者,OLE剪贴板使用延迟供应模式.OLE剪贴板会创建一个隐藏窗口作为剪贴板的拥有者(OpenClipboard需要HWND参数)--在OleInitialize()中创建.
    173. 3.OLE枚举IDataObject的格式,同时对每个在全局句柄中提供数据的格式调用SetClipboard().标准剪贴板不支持文件和结构的传输入,所以只能将全局句柄放在剪贴板上.
    174. 4.数据消耗者访问剪贴板.当它不知道OLE的信息时,使用标准方式GetClipboardData()来获取数据--数据是由延迟供应方式提供的.OLE剪贴板查询IDataObject接口,然后调用接口上的GetData()方法取得数据.如数据消耗者支持OLE,它可用OleGetClipboard()取得IDataObject指针,并用GetData()取得数据.

    175. MFC的IDataObject支持

    176. .COleDataSource:一个完全的COM对象,实现了IDataObject接口.常用在数据提供者一方.
    177. .COleDataObject:封装一个IDataObject指针,为开发者提供C++接口.常用在数据消耗者一方.

    178. A.通过剪贴板传输数据

    179. 1.将数据放置到剪贴板中.
    180. 得到数据指针并创建COleDataSource的一个实例,用这个对象来保存数据.例:
    181. {
    182. LPCTSTR source = GetString() ;
    183. COleDataSource *pCods;
    184. HGLOBAL h = GlobalAlloc(GHND|GMEM_SHARE,(_tcslen(source)+1)*sizeof(TCHAR));
    185. _tcscpy( LPSTR(GloballLock(h)), source ) ;
    186. GlobalUnlock(h);//使用全局内存时这句一定要有.
    187. pCods->CacheGlobalData(CF_TEXT,h) ;
    188. pCods->SetClipboard() ;
    189. //没有释放全局内存?在将数据放到OLE剪贴板的情况下,OLE自己会去释放它.
    190. //不想使用全局内存?那用COleDataSource::CacheData()放入数据源对象,但需要提供两个描绘数据的参数.
    191. }
    192. 2.从剪贴板中粘贴数据
    193. 声明一个COleDataObject的实例,调用COleDataObject::AttachClipboard().可用ColeDataObject::IsDataAvailable()获取数据格式;但也支持COleDataObject::BeginEnumFormats()/COleDataObject::GetNextFormat()枚举所有格式.
    194. 确定格式后,用COleDataObject的以下函数可得到数据:
    195. .COleDataObject::GetDataObject();//最通用的,处理所有格式.
    196. .COleDataObject::GetFileData();//数据的存储介质是文件时;文件由使用者释放.
    197. .COldDataObject::GetGlobalData();//数据在全局内存.
    198. 例:
    199. {
    200. COleDataObject odo ;
    201. odo.AttachClipboard() ;
    202. if( odo.IsDataAvailable(CT_TEXT)){
    203. HANDLE h = odo.GetGlobalData(CF_TEXT);
    204. //use data
    205. GlobalUnlock(h) ;
    206. GlobalFree(h) ;
    207. }
    208. odo.Release() ;
    209. }
    210. B.延迟供应.
    211. 由COldDataSource中的DelayRenderData(),DelayRenderFileData(),OnRenderData()实现.需要在COleDataSource派生类中实现OnRenderData().类似的函数还有OnRenderFileData,OnRenderGlobalData().

    212. //-----------------------------------------------------------

    213. OLE拖放

    214. 使用3个接口:IDataObject,IDropSource(COleDropSource实现),IDropTarget(COleDropTarget实现).

    215. 控制键:[没有]=移动数据;[CONTROL]=复制数据;[CONTROL-SHIFT]=建立快捷方式;[ALT]=移动数据

    216. 开起拖放:与将数据放在剪贴板相似,不过是调用COldDataSource:oDragDrop()而不是COleDataSource::SetClipboard();
    217. 结束播放:放置目标通常需要两个COleDropTarget与CView类
    218. 1.注册CView为一个COleDropTarget类.在类中声明一个COleDropTarget变量,在OnCreate()中调用COleDropTarget::Register(this);
    219. 2.重载CView类的OnDragEnter(),OnDragOver(),OnDragLeave(),OnDrop();
    复制代码

     

     

     

     

    VC的剪贴板操作
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-11-1 10:19 , Processed in 0.123659 second(s), 24 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表