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



本文转自jazka 51CTO博客,原文链接:http://blog.51cto.com/jazka/219089,如需转载请自行联系原作者

相关文章
|
移动开发 HTML5
HTML5的基本结构
HTML5的基本结构。
128 5
|
C++ 索引
Windows10下VS2015下载安装详解【附“安装包丢失或损坏“ 错误解决方法】
Windows10下VS2015下载安装详解【附“安装包丢失或损坏“ 错误解决方法】
8864 0
Windows10下VS2015下载安装详解【附“安装包丢失或损坏“ 错误解决方法】
|
12月前
|
调度 开发者
深入理解:进程与线程的本质差异
在操作系统和计算机编程领域,进程和线程是两个核心概念。它们在程序执行和资源管理中扮演着至关重要的角色。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
347 5
|
编译器 Go API
go generate指南:代码自动生成
go generate指南:代码自动生成
3900 0
|
Java 数据库
成功解决: 加上 @Transient 仍然报 Unknown column ‘goods_list‘ in ‘field list‘
这篇文章讨论了在SpringBoot结合MyBatis-Plus框架中,当实体类中包含另一个实体类的集合,而这个集合字段在数据库中不存在时,如何避免由此引发的错误。文章提供了两种解决方法:一是使用`@TableField(exist = false)`注解明确指定该字段在数据库中不存在;二是使用`transient`关键字,但要注意`transient`关键字在Java中默认就是被忽略的,不需要加`@Transient`注解。文章最后展示了问题解决的效果。
|
编解码 Linux 虚拟化
超详细VMware虚拟机安装Win10操作系统过程图解
这篇文章提供了一个详细的VMware虚拟机安装Windows 10操作系统的图解教程,包括了从创建虚拟机到安装操作系统的全过程,以及安装后的一些基本设置,如屏幕分辨率调整等。作者还提到了后续会分享关于磁盘分区的创建过程。
超详细VMware虚拟机安装Win10操作系统过程图解
|
Java Spring
【亲测有效完结bug】org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exce
【亲测有效完结bug】org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exce
1563 0
|
存储 人工智能 多模数据库
数据库技术前沿:探索其发展趋势与应用
一、引言 数据库技术作为现代信息技术体系中的关键一环,不仅为企业和组织提供了高效、安全的数据存储和管理手段,还在大数据、云计算、人工智能等前沿领域发挥着重要作用
|
机器学习/深度学习 算法 atlas
RAG 2.0架构详解:构建端到端检索增强生成系统
RAG(检索增强生成)旨在通过提供额外上下文帮助大型语言模型(LLM)生成更精准的回答。现有的RAG系统由独立组件构成,效率不高。RAG 2.0提出了一种预训练、微调和对齐所有组件的集成方法,通过双重反向传播最大化性能。文章探讨了不同的检索策略,如TF-IDF、BM25和密集检索,并介绍了如SPLADE、DRAGON等先进算法。目前的挑战包括创建可训练的检索器和优化检索-生成流程。研究表明,端到端训练的RAG可能提供最佳性能,但资源需求高。未来研究需关注检索器的上下文化和与LLM的协同优化。
1981 1
|
分布式计算 运维 DataWorks
MaxCompute产品使用问题之数据如何导出到本地部署的CK
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
189 1