分享

调用哪个API函数可以实现复制和粘贴?

 玉郡书屋 2015-10-13
 一、概述      ----   在Windows操作系统中存在两种剪贴板机制:Windows标准剪贴板和OLE剪贴板机       制。       ----   标准的Windows剪贴板是一个被所有Windows应用程序共享的系统服务,因此它并      没有自己的句柄或类。但你可以通过CWnd类的成员函数来管理剪贴板。      ----   自从OLE(Object   Linking   and   Embedding,对象链接和嵌入)诞生之后,       Windows操作系统中便出现了第二种剪贴板机制——OLE剪贴板机制。标准的Windows剪       贴板API(Application   Programming   Interface,应用程序编程接口)依然可用,但是       他已经被OLE数据传输机制来实现了。OLE支持UDT(Uniform   Data   Transfer,统一数据       传输),并可以通过拖放操作实现剪贴板的剪切、复制和粘贴等操作。OLE剪贴板除了       拥有标准Windows剪贴板的性能外,还支持传输用户自定义的剪贴板格式,并能够在传       输数据时绑定OLE格式(如字体、字号等)。OLE剪贴板机制将成为更为主要的数据传输       机制。       ----   本文将简要叙述标准Windows剪贴板的实现,并将重点放在讨论如何通过Visual       C++实现OLE剪贴板上。       ----   二、选择适当的剪贴板机制       ----   在选择使用何种剪贴板机制时通常应遵循下面的原则:       ----   如果应用程序在将来又可能具有新的性能(比如现在只需要传输纯文本,但将来       有可能需要另外传输字体等特性),那么使用OLE剪贴板。       ----   如果你正在使用一个OLE应用程序,或者你希望使用任何OLE特性(如拖放等)那       么你应当使用OLE剪贴板机制。       ----   如果你提供了OLE格式(如字体、字号等),那么使用OLE剪贴板机制。       ----   三、使用Windows标准剪贴板       ----   大多数Windows下的应用程序支持剪切或复制数据到Windows剪贴板中以及从剪贴       板粘贴数据至目的地。在这个过程中,剪贴板数据格式在多种应用程序之间发生了变       化。系统构架仅仅通过实现一些有限的类来支持一些有限的剪贴板格式,下表列出了      Windows标准剪贴板支持的格式(第一列“值”将在下面的程序代码中使用)。       值   含义       CF_BITMAP   一个对应于位图的句柄(HBITMAP)。      CF_DIB   一个包含BITMAPINFO结构并且       跟着位图数据的内存对象。       CF_DIF   数据交互格式      CF_DSPBITMAP   有一个私有格式的位图显示格式。       CF_DSPENHMETAFILE   有一个私有格式的增强的元文件的显示格式。       CF_DSPMETAFILEPICT   有一个私有格式的元图显示格式。       CF_DSPTEXT   有一个私有格式的文本显示格式。       CF_ENHMETAFILE   一个增强的元文件(HENHMETAFILE结构)的句柄。       CF_GDIOBJFIRST到   CF_GDIOBJLAST   应用软件定义       的一系列GDI对象的整型值。       CF_HDROP   一个HDROP类型的句柄,用来标识一列文件。       CF_METAFILEPICT   一个使用METAFILEPICT结构定义的元图文件的句柄。       CF_OEMTEXT   预定义的字符的文本格式,每一行都绑定       一个CR-LF字符,并且用一个空字符表示数据结尾。       CF_OWNERDISPLAY   剪贴板拥有者的显示格式,       剪贴板的拥有者必须显示并且更新剪贴板的观察器窗口,       并且接收WM_ASKCBFORMATNAME、WM_HSCROLLCLIPBOARD、       WM_PAINTCLIPBOARD、WM_SIZECLIPBOARD以及       WM_VSCROLLCLIPBOARD等消息,hMem参数必需为NULL。       CF_PALETTE   调色板的句柄       CF_PRIVATEFIRST到CF_PRIVATELAST   私有的剪贴板格式的整型值。       CF_RIFF   能够提交比CF_WAVE标准波表文件格式更为复杂的音频数据       CF_SYLK   微软公司的SYLK(Symbolic   Link,符号链接)格式       CF_TEXT   文本格式       CF_WAVE   使用一种标准波表文件格式如11kHz或22kHz等       PCM(Pulse   Code   Modulation,脉冲编码调制器)提交音频数据。       CF_TIFF   TIFF图形格式       CF_UNICODETEXT   Unicode文本格式(       注意:仅适用于Windows   NT或Windows   2000操作系统)           ----   表1 常用的标准剪贴板格式      ----   要编写一个实现剪切和复制命令的函数,就要在你的应用程序中实现选定操作;       要编写一个实现粘贴命令的函数,就需要请求剪贴板来检测它是否包含你的应用程序能       够支持的数据。下面的代码实现了复制命令,其它实现可仿照进行,在此不再赘言。       ----   程序示例:       void   CMyView::OnEditCopy()       {       if   (   !OpenClipboard()   )       {       AfxMessageBox(   "无法打开剪贴板"   );       return;       }      //   删除目前剪贴板的内容       if(   !EmptyClipboard()   )       {       AfxMessageBox(   "无法清除剪贴板"   );       return;       }       //   获取选定的数据       //   检查是否为剪贴板支持的格式       if   (   ::SetClipboardData(   CF_??,   hData   )   ==   NULL   )       //   CF_??指定了剪贴板中数据的格式,       //表1列出了标准的剪贴板格式       {       AfxMessageBox(   "无法将数据复制到剪贴板当中"   );       CloseClipboard();       return;       }       //   ...       CloseClipboard();       }               ----   四、使用OLE剪贴板机制       ----   首先举个例子给你一些关于OLE剪贴板的感性认识,同时说明你需要为OLE剪贴板       做哪些事情:Microsoft   Excel为工作表注册了一个自定义的格式,这个格式能够比其       它标准格式(如位图或纯文本等)提供更多的信息。当此数据被粘贴到一个支持工作表       的程序(比如Lotus   1-2-3)时,所有的原工作表中的公式和数值将被保留,并且还可       能会根据需要被更新。Excel同样将数据以OLE格式存放在剪贴板中,这样它就可以作为       一个OLE对象被嵌入。任何OLE文档包容器(Container)(比如Microsoft   Word)能够       将该数据作为嵌入对象粘贴进文档(比如通过“选择性粘贴”,可以在Word中粘贴进       Excel工作表对象)。这个嵌入对象能够通过激活Microsoft   Excel来进行修改(在Word       中可以通过双击对象实现)。该工作表甚至可以被粘贴到一个绘图程序(比如的画       笔)。当然,这时你无论如何都没有办法将其中的数据像在工作表中一样修改,因为它       已经是图片了。      ----   从上例总结一下,我们应当作的事情大致有:注册自定义的格式、传输格式到剪       贴板上以及实现复制、剪切和粘贴。       ----   注册自定义格式       ----   OLE剪贴板中的数据存在于多种格式。当一个用户选择从剪贴板粘贴数据时,应用       程序应当能够选择使用何种格式粘贴数据。应用程序应当提供大部分格式的信息,除非       用户指定使用某一种特定格式粘贴(比如只粘贴文字或只粘贴图片等)。       ----   Windows定义了很多能够通过剪贴板传输的标准格式(见表1),OLE也定义了很多      特殊的格式。应用程序可以通过获取更加详细的信息来注册他们自己的剪贴板格式。这       可以通过使用Win32   API函数RegisterClipboardFormat来实现:       ----   RegisterClipboardFormat   (   lpszFormat   );       ----   说明   lpzxFormat是指向一个字符串的指针,用以命名自定义的格式。该函数返回       无符号整数,该数即为格式的ID号       ----   在注册了自定义的格式之后,便可以使用RegisterClipboardFormat函数的返回值       来标识并使用该格式。       ----   将格式传输到剪贴板上       ----   要增加更多的格式到剪贴板上,你必须从COleClientItem或COleServerItem继承       一个类,并且在该类中重载OnGetClipboardData函数。在这个函数中,你应当做按照下       列步骤完成。       ----   将更多的格式放置在剪贴板上       ----   1.   建立一个COleDataSource对象。       ----   2.   传递该数据源到一个函数,用该函数通过访问       COleDataSource::CacheGlobalData函数来将你的数据格式添加到支持的格式列表。       ----   3.   通过访问COleDataSource::CacheGlobalData,为每一个你向支持的格式添加       标准格式。       ----   程序示例:       COleDataSource*   CMyItem::OnGetClipboardData(       BOOL   bIncludeLink,LPPOINT   pptOffset,   LPSIZE   pSize)       {       ASSERT_VALID(this);           if   (m_pServerNode   ==   NULL)       return   NULL;           COleDataSource*   pDataSource   =       new   COleDataSource;       TRY       {       GetNativeClipboardData(pDataSource);       GetClipboardData(pDataSource,   bIncludeLink,       pptOffset,   pSize);       }       CATCH_ALL(e)       {       delete   pDataSource;       THROW_LAST();       }       END_CATCH_ALL           ASSERT_VALID(pDataSource);       return   pDataSource;       }           ----   复制、剪切和粘贴数据       ----   将数据复制或剪切到剪贴板上       ----   1.   确定将要被复制的数据是一个本地数据还是一个嵌入对象或链接。       ----   如果数据是一个嵌入对象或链接,创建一个指向被选定数据的COleClientItem指       针。       ----   如果数据是本地化的并且应用程序是一个服务器,那么从COleServerItem继承一       个新的类,并创建该对象。否则,为数据建立一个COleDataSource对象。       ----   2.   访问选定对象的CopyToClipboard成员函数。       ----   3.   如果用户选择剪切命令而不是复制,那么从你的应用程序中删除那些数据。       ----   程序示例:       void   CMainView::OnEditCut()       {       ASSERT(m_pSelection   !=   NULL);       TRY       {       m_pSelection-   >CopyToClipboard(TRUE);       OnEditClear();       }       CATCH_ALL(e)       {       AfxMessageBox(IDP_CLIPBOARD_CUT_FAILED);       }       END_CATCH_ALL       }           void   CMainView::OnEditCopy()       {       ASSERT(m_pSelection   !=   NULL);       TRY       {       m_pSelection-   >CopyToClipboard(TRUE);       }       CATCH_ALL(e)       {       AfxMessageBox(IDP_CLIPBOARD_COPY_FAILED);       }       END_CATCH_ALL       }           ----   从剪贴板粘贴数据       ----   粘贴数据比复制更加复杂,因为你需要选择粘贴的格式。       ----   1.   在你的视中,实现OnEditPaste来处理用户从编辑菜单选择粘贴命令的操作。       ----   2.   在OnEditPaste函数中,建立一个COleDataObject对象并且访问它的       AttachClipboard成员函数来将这个对象绑定到剪贴板。       ----   3.   访问COleDataObject::IsDataAvailable函数来检查是否可以使用特殊的格       式。当然,你也可以通过循环使用COleDataObject::BeginEnumFormats来寻找其它格式       直到你找到了最适合的格式。       ----   4.   粘贴数据。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多