精华内容
下载资源
问答
  • windows剪贴板(ClipBoard)是内存中的一块区域,是Windows内置的一个非常有用的工具。通过小小的剪贴板,架起了一座彩桥,使得在各种应用程序之间,传递和共享信息成为可能。 (推荐学习:phpstorm)然而美中不足的是...

    d01e90c452c98221728716248c848b3c.png

    windows中剪贴板(ClipBoard)是内存中的一块区域,是Windows内置的一个非常有用的工具。

    通过小小的剪贴板,架起了一座彩桥,使得在各种应用程序之间,传递和共享信息成为可能。 (推荐学习:phpstorm)

    然而美中不足的是,剪贴板只能保留一份数据,每当新的数据传入,旧的便会被覆盖。

    剪贴板的工作原理

    剪贴板是Windows系统一段可连续的。可随存放信息的大小而变化的内存空间,用来临时存放交换信息。

    内置在windows并且使用系统的内部资源RAM,或虚拟内存来临时保存剪切和复制的信息,可以存放的信息种类是多种多样的。

    剪切或复制时保存在剪贴板上的信息,只有再剪贴或复制另外的信息,或停电、或退出windows,或有意地清除时,才可能更新或清除其内容,即剪贴或复制一次,就可以粘贴多次。

    在Windows不同应用程序中使用剪贴板

    在Windows内部,不同的应用程序共享同一剪贴板,因而即使你使用的是不同的应用程序,剪贴板也能工作得很好。具体操作步骤如下:

    1.打开应用程序①,让包含源信息的窗口出现在桌面上。

    2.用鼠标选择要剪贴或复制的信息,然后点击工具栏中的复制或剪贴按钮(或打开菜单,选择剪贴或复制命令项),如果你觉得麻烦,你也可使用键盘操作,“ctrl+x”代表剪切,“ctrl+c”代表复制。

    3.启动应用程序②,打开目标文件,将光标定位到插入点,单击工具栏中的粘贴按钮(或打开菜单选择“粘贴”项),或使用键盘上的“ctrl+v”组合键。

    展开全文
  • Windows进程通信之剪贴板

    千次阅读 2014-08-01 14:03:40
    本文从剪贴板概念、剪贴板内容监听,普通数据类型,打开剪贴板,读剪贴板,写剪贴板、API汇总、他山之石、通过剪贴板实现进程间通信和总结共11个方面来较为深入地探讨Windows剪贴板的机制和使用。   说明:建议先...

    本文由danny发表于http://blog.csdn.net/danny_share

     

    前面两篇废话了这么多,本文开始上干货。

    本文从剪贴板概念、剪贴板内容监听,普通数据类型,打开剪贴板,读剪贴板,写剪贴板、API汇总、他山之石、通过剪贴板实现进程间通信和总结共10个方面来较为深入地探讨Windows剪贴板的机制和使用。

     

    说明:建议先下载本文配套工程,其中

    (1)      ClipBoardDemo工程主要演示剪贴板相关API使用

    (2)      MainProcess工程、ASubProcess工程、BSubProcess工程分别用于演示本文第九部分进程间通信的主进程和两个子进程

    下载地址:http://download.csdn.net/detail/danny_share/7703279

     

    一.剪贴板概念

    剪贴板是系统级的堆空间,且任何一个应用程序都具备访问权,主要涉及复制(Ctrl+C),剪切(Ctrl+X)、粘贴(Ctrl+V)、清空和监听五个操作。

     

    二.剪贴板内容监听

    1.开始监听

    【a】SetClipboardViewer将窗口加入监听链

    【b】一旦剪贴板内容变化,系统会向监听链中的第一个注册监听的窗口发送WM_DRAWCLIPBOARD消息。为什么说是第一个呢?参见“消息链顺序”

    【c】通过实验发现,如果新拷贝的内容和原来一样,系统还是会出发消息,说明普通的复制操作不管内容相不相同,都是直接覆盖原来剪贴板中的数据的

     

    2.处理消息

    (1)WM_CHANGECBCHAIN

    【a】除自己以外,其他进程加入了监听链,或者退出了监听链,系统就会发出这个消息

    【b】这里只说明监听者发生了变化,并不表示剪贴板中内容发生变化。

    【c】如果存在下一个监听进程,那么需要将该消息发送给下一个监听者

         否则下一个监听者将收不到该消息

    【d】对于MFC,可通过重载OnChangeCbChain函数实现

     

    (2)WM_DRAWCLIPBOARD

    【a】进程首次运行时或者是剪贴板内容发生变化时,进程都会收到这个消息

    【b】如果存在下一个监听进程,那么需要将该消息发送给下一个监听者

    否则下一个监听者将收不到该消息

    【c】对于MFC,可通过重载OnDrawClipboard函数实现

     

    3.停止监听

    【a】使用ChangeClipboardChain()函数停止监听

    【b】本质是发送WM_CHANGECBCHAIN消息,且将自己从监听链中去除

    【c】其他监听进程将会收到WM_CHANGECBCHAIN消息

     

    4.消息链顺序

    【a】刚才一直在说当剪贴板内容变化时,进程将会收到WM_DRAWCLIPBOARD消息,然后该进程处理完以后,需向下个监听者发送该消息,那下个监听者是谁呢?

    【b】我们在WM_DRAWCLIPBOARD消息处理函数OnDrawClipboard中closeClipboard后sleepl两秒后弹窗

    【c】然后拷贝ClipBoardOne.exe三份,依次启动,我们分别取名A、B和C

    【d】当剪贴板内容变化时,进程弹出剪贴板变化的顺序也是A、B、C,说明加入监听的顺序和收到消息的顺序是一致的。

     

    三.数据类型

    分类

    ID

    格式

    说明

    标准

    1

    CF_BITMAP

    位图句柄

    2

    CF_DIB

     

    3

    CF_DIBV5

    包含BITMAPV5HEADER结构且跟着位图颜色空间和位图数据

    4

    CF_DIF

     

    5

    CF_DSPBITMAP

     

    6

    CF_DSPENHMETAFILE

     

    7

    CF_DSPMETAFILEPICT

     

    8

    CF_DSPTEXT

     

    9

    CF_ENHMETAFILE

     

    10

    CF_GDIOBJFIRST

     

    11

    CF_GDIOBJLAST

     

    12

    CF_HDROP

    拖放服务,文件拷贝也是这个类型

    13

    CF_LOCALE

     

    14

    CF_METAFILEPICT

     

    15

    CF_OEMTEXT

    在窗口中执行DOS一起使用剪贴板

    16

    CF_OWNERDISPLAY

     

    17

    CF_PALETTE

    调色板句柄,通常和CF_DIB配合

    18

    CF_PENDATA

     

    19

    CF_PRIVATEFIRST

     

    20

    CF_PRIIVATELAST

     

    21

    CF_RIFF

    资源交换文件格式的多媒体数据

    22

    CF_SYLK

     

    23

    CF_TEXT

    ANSI文本

    24

    CF_TIFF

    TIFF格式图片数据内存块

    25

    CF_UNICODETEXT

    Unicode格式字符

    26

    CF_WAVE

    wave文件

    注册

    27

    自定义数值

    RegisterClipboardFormat自定义格式

    私有

    28

    值范围

    CF_PRIVATEFIRST

    CF_PRIVATELAST

    (1)     不需要向系统注册

    (2)     WM_DESTROYCLIPBOARD消息释放资源

    多重

    29

     

     

    实质没有新定义格式

    (1)     CoutClipboardFormats查询格式总数

    (2)     要返回具体格式,EnumClipboardFormats

    转换

    30

    (1)     当剪贴板中为格式A,而Windows需格式B,假如A转成B在左侧表格中,则系统默认转换

    (2)     例如拷贝BMP文件时,由于BMP文件和系统调色板相关,所以最好格式为CF_DIB或CF_DIBVS,这样系统请求CF_BITMAP时,会自动使用调色板



    四.打开剪贴板

    (1)打开剪贴板之前,我们首先需要查看是否有其他应用正在使用剪贴板

    (2)Windows提供了两个和查看拥有者相关的函数,分别是

    GetClipboardOwner和GetOpenClipboardWindow

    (3)GetClipboardOwner函数一般指上次存放数据的进程

    (4)GetOpenClipboardWindow才是真正指当前获得剪贴板操作权的进程

    (5)因此OpenClipboard前需调用GetOpenClipboardWindow函数,当返回句柄为空才行。

    HWND myHwnd=GetSafeHwnd();//当前窗口进程
    CWnd* ownerCHwnd=GetClipboardOwner();//一般指上次使用读写剪贴板的进程
    CWnd* wndUserCHwnd=GetOpenClipboardWindow();//这才是真正的当前取得剪贴板使用权的进程
    


    (6)根据前面的分析,进程打开剪贴板使用完毕以后,一定要调用CloseClipboard交出使用权,否则其他进程将无法取得剪贴板使用权

     

    五.读剪贴板

    (1)读剪贴板之前,首先还是打开剪贴板,读完以后关闭剪贴板

    (2)假如想读取特定格式的数据,则可先用IsClipboardFormatAvailable来判断该格式是否存在。

    (3)读文本CF_TEXT

    <pre name="code" class="cpp">void*tempData=NULL;
        if(this->myClip->readData(CBType_Text,&tempData))
        {
           char* test=(char*)tempData;
           CStringinfo="Read Success , the content is:\r\n";
           info+=test;
           MessageBox(info,MB_OK);
        }
        else
        {
           MessageBox("Read Failed",MB_OK);
        }
    


     
    

    (1)读图片CF_BITMAP

    这里复制时不是复制图片文件,而是类似于在浏览器里右击复制图片

    这里我复制了百度首页的logo。原理跟读取CF_TEXT一样,先读出一个HBITMAP句柄,再保存成图片即可

       

    (2)读文件CF_HDROP

    【a】本质上是得到文件路径

    【b】打开剪贴板前需

    UINTuDropEffect=RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);

    注意,Windows系统在ShlObj.h文件中

    <pre name="code" class="cpp">#define CFSTR_PREFERREDDROPEFFECT           TEXT("Preferred DropEffect")
    


     
    

    【c】通过DragQueryFile函数可遍历剪贴板中文件,先传入0得到一个UNIT指,而后将该值迭代传参即可

     

    (3)枚举剪切板中所有格式

    存在两个枚举格式相关函数。分别是

    <pre name="code" class="cpp">CountClipboardFormats()   //此函数是获取格式总数
    EnumClipboardFormats()    //首次传0,以后用返回值迭代,即可遍历
    


     
    

    六.写剪贴板

    都比较简单,详见ClipBoardDemo工程

    1.写文本CF_TEXT

    2.写图片CF_BITMAP

    3.写文件CF_HDROP

    (1)对于拷贝,标志位是DROPEFFECT_COPY

    (2)对于剪切,标志位是DROPEFFECT_MOVE

    4.写多种格式

    原理一样,只要写数据的时候不清空,多种格式写完以后再关闭剪贴板即可。

     

    七.API汇总

    (1)MFC提供了两组本质是一样的API,一组属于全局函数,一组属于窗口的成员函数(全局函数中需传窗口句柄的函数都被MFC封装了一层)。

    (2)我们在窗口button里调用this-> OpenClipboard(),然后debug F11进入观察一下

    <pre name="code" class="cpp">_AFXWIN_INLINE BOOLCWnd::OpenClipboard()
        {ASSERT(::IsWindow(m_hWnd)); return::OpenClipboard(m_hWnd); }
    


     
    

    所以窗口成员剪贴板函数实质上调用的仍是全局函数,不过在内部多传了个句柄

    (3)所以我们自己封装时,也可借此思路,内部多传个句柄封装。

    ID

    函数

    功能

    1

    SetClipboardViewer

    监听剪贴板

    2

    ChangeClipboardChain

    取消监听剪贴板

    3

    OnChangeCbChain

    剪贴板监听对象变化事件

    4

    OnDrawClipboard

    剪贴板内容变化事件

    5

    AddClipboardFormatListener

    添加某种格式的监听

    6

    RemoveClipboardFormatListener

    去除某种格式的监听

    7

    GetClipboardSequenceNumber

    获取在监听链中的顺序

    8

    EnumClipboardFormats

    枚举格式

    9

    CountClipboardFormats

    获取格式数量

    10

    GetPriorityClipboardFormat

    获取最符合的格式

    11

    GetClipboardFormatName

    获取非预定义的格式名称

    12

    IsClipboardFormatAvailable

    判断剪贴板中是否含有目标格式

    13

    RegisterClipboardFormat

    注册格式

    14

    GetUpdatedClipboardFormats

    获取当前支持的格式

    15

    OpenClickborder

    打开剪贴板,取得使用权

    16

    CloseClipboard

    关闭剪贴板,释放使用权

    17

    GetClipboardViewer

    获取剪贴板监听链的第一个窗口句柄

    18

    GetOpenClipboardWindow

    获取当前正在使用剪贴板的窗口句柄

    19

    GetClipboardOwner

    一般指上次向剪贴板写数据的对象

    20

    EmptyClipboard

    清空剪贴板

    21

    SetClipboardData

    写数据,第二个参数NULL表示延迟写入

    22

    GetClipboardData

    读数据

    八.他山之石

    1.迅雷

    当我们复制文本时,如果剪贴板中包含链接地址,且是迅雷支持的下载格式,则迅雷会弹出下载对话框,这其实就是使用了剪贴板的监听原理

     

    2.QQ

    我们在QQ聊天界面里粘贴时,如果之前复制的是文字,则文字内容复制到了输入框中,如果之前复制的是文件,则文件直接发给对方好友了。其原理就是在粘贴的时候判断当前剪贴板中到底是什么内容,然后做出不同的处理

    九.通过剪贴板实现进程间通信

    (1)需求设计

    好,原理说了这么多,现在来实现我们在“Windows进程间通信之目录”中所说的需求,我们下面简化需求,形成下面的模型:

    【a】  一个主进程启动两个子进程

    【b】  主进程可随时发送不同的命令给不同的子进程

    【c】  子进程收到命令以后去做相应的操作,完成后发送响应给主进程

    【d】  主进程收到子进程的响应后,再做相应处理

    使用剪贴板的思维来实现上述需求:

    【a】  三个进程都监听剪贴板

    【b】  设计协议格式,使得进程读取剪贴板中数据即可区分相关参数

    我们简化,在剪贴板中放置纯文本数据来传输数据,协议格式如下:

    (2)实现

    贴上主进程关键代码,其他详见工程

    voidCMainProcessDlg::analysisClipboard()
    {
        CBProtocolStructtempData;
        m_protocol->getProtocolData(tempData);
     
        if(tempData.receiver=='M')
        {
           if(tempData.sender='A')
           {
               if(tempData.command=='0')
               {
                  CStringinfo="A Sub Process send Work response to MainProcess\r\nthe Data is ";
                  info+=tempData.data;
                  MessageBox(info,"Info",MB_OK);
               }
               else
               {
                  if(tempData.command=='1')
                  {
                      CStringinfo="A Sub Process send Close response toMain Process\r\nthe Data is ";
                      info+=tempData.data;
                      MessageBox(info,"Info",MB_OK);
                  }
               }
           }
           else
           {
               if(tempData.sender='B')
               {
                  if(tempData.command=='0')
                  {
                      CStringinfo="B Sub Process send Work response to MainProcess\r\nthe Data is ";
                      info+=tempData.data;
                      MessageBox(info,"Info",MB_OK);
                  }
                  else
                  {
                      if(tempData.command=='1')
                      {
                         CStringinfo="B Sub Process send Close response toMain Process\r\nthe Data is ";
                         info+=tempData.data;
                         MessageBox(info,"Info",MB_OK);
                      }
                  }
               }
           }
        }
    }
    voidCMainProcessDlg::OnDrawClipboard()
    {
        CDialog::OnDrawClipboard();
     
        if(NULL!=this->nextWindow)
        {
           ::SendMessage(nextWindow,WM_DRAWCLIPBOARD, 0, 0);
        }
        analysisClipboard();
    }
    

    另外贴上子进程A的关键函数

     

    void CASubProcessDlg::analysisClipboard()
    {
    	CBProtocolStruct tempData;
    	m_protocol->getProtocolData(tempData);
    
    	if(tempData.receiver=='A')
    	{
    		if(tempData.sender='M')
    		{
    			if(tempData.command=='0')
    			{	
    				CBProtocolStruct responseData;
    				responseData.sender='A';
    				responseData.receiver='M';
    				responseData.command='0';
    				m_protocol->setProtocolData(responseData);
    				MessageBox("A receive Work command","Info",MB_OK);
    			}
    			else
    			{
    				if(tempData.command=='1')
    				{
    					CBProtocolStruct responseData;
    					responseData.sender='A';
    					responseData.receiver='M';
    					responseData.command='1';
    					responseData.data='Z';
    					m_protocol->setProtocolData(responseData);
    					MessageBox("A receive Close command","Info",MB_OK);
    
    					SendMessage(WM_CLOSE,0,0);
    				}
    			}
    		}
    	}
    }
    void CASubProcessDlg::OnDrawClipboard()
    {
    	CDialog::OnDrawClipboard();
    
    	if(NULL!=this->nextWindow)
    	{
    		::SendMessage(nextWindow, WM_DRAWCLIPBOARD, 0, 0);
    	}
    	analysisClipboard();
    
    }
    

    (1)  时序

    我们以主进程向A发送MA00为例,来解析整个命令时序

    【a】  第2步中A感知变化后第3步是B感知变化,而不是A处理变化的是因为,在OnDrawClipboard中是先SendMessage,然后再处理的。

    void CASubProcessDlg::OnDrawClipboard()
    {
        CDialog::OnDrawClipboard();
     
        if(NULL!=this->nextWindow)
        {
           ::SendMessage(nextWindow,WM_DRAWCLIPBOARD, 0, 0);
        }
        analysisClipboard();
    }

    【b】剪贴板内容变化后,感知顺序都是先A再B再M,是因为,我们启动程序的顺序就是A、B和M(参见本文第二部分监听剪贴板内容消息链顺序一节)

     

    十.总结

    优点:

    (1)  原理简单,上手很快

    (2)  支持不同的数据格式

     

    缺点:

    (1)后台虽有两个子进程,但由于剪贴板权限只有一个,无法实现两个子进程同时操作;

    (2)剪贴板更适合传输数据,虽提供剪贴板监听机制达到传输命令和时序的目的,但需自己额外设计数据格式,比较繁琐,不像Windows多线程拥有众多基础设施。所以适合主子进程间命令交互不频繁、数据交互较多的应用。


    Danny

    2014年8月1号

    于天津河西


    展开全文
  • 电脑的剪切是我们常常会用到的,只要...剪切指Windows操作系统提供的一个暂存数据,并且提供共享的一个模块。也称为数据中转站,剪切在后台起作用,在内存里,是操作系统设置的一段存储区域。其实它存在与所...

    电脑的剪切板是我们常常会用到的,只要我们有进行复制粘贴。不过有朋友好奇电脑剪切板在哪,怎么找不到,那么Windows7电脑剪切板在哪呢?其实这个问题很简单,下面就由小编来带大家找到Windows7电脑的剪切板吧!

    电脑的剪切板是什么?

    剪切板是指Windows操作系统提供的一个暂存数据,并且提供共享的一个模块。也称为数据中转站,剪切板在后台起作用,在内存里,是操作系统设置的一段存储区域。其实它存在与所有的操作系统里,包括WindowsXP系统剪贴板、Windows7系统剪贴板、Windows8系统剪贴板,在硬盘里是找不到它的,你只要有文本输入的地方按Crtl+V或右键粘贴就出现了,它里面的内容会被新的内容送到剪切板后,遭到覆盖的。

    电脑的剪切板有什么用?

    当你对可编辑的文本进行操作时,如果想把目标文字文本转移到其他的区域,这时候要用到电脑的剪切命令,此时,被剪切的内容就会出现在剪切板内,然后就可以通过粘贴命令把里面的内容放到目标位置,如果没有新的内容进来,之前的内容一般都会继续存在。

    电脑的剪切板怎么用?

    具体的怎么使用剪切板其实大家一般都能用到的,当你对文本文字进行操作时,主要是复制(Ctrl+C)和剪切(Ctrl+X)操作,剪切板内都会被用到。

    8384a643d67674299e3f3f4d52200ebd.png

    怎么打开电脑的剪切板?

    电脑的剪切板到底能不能打开查看呢?其实是可以的,一般对WindowsXP系统和Windows7系统进行clipbrd操作时,剪切板只会一闪而过,你根本看不到任何内容,只能看到一个dos窗口一闪即逝,那么如何查看电脑系统的剪切板呢?必须利用第三方软件才好查看剪切板,这里推荐一个软件,clipbrd.exe,利用他你就可以打开电脑的剪切板并且查看了。

    1、下载clipbrd.exe这个软件,注意在你的系统安全软件查杀时放行,不然就用不起来了。

    2、直接打开软件界面如下,左下角有个最小化的窗口,如果看不到,那么你把右边的滚动条操作一下,即可以找到,然后最大化。

    f87c14f3fa00f7952ded4b77a830c25e.png

    3、如下,里面的内容就是我刚刚复制的内容(剪切和复制的内容都会出现在这里),这样就可以查看电脑剪切板了。

    fa750162fc8e117832207dad8ff613d4.png

    4、如果想快速打开clipbrd.exe,你可以把下载后的clipbrd.exe文件放到系统文件夹Windows/System32下。

    1653c769f79911eb8d7242d6c5ef646e.png

    5、通过“运行”操作,快速打开电脑剪切板查看,通过Windows键+R键快捷键打开“运行”,输入“clipbrd”,确定后打开查看剪切板内容。

    9ca5046ebb376880b6d71bd71bc857a5.png

    6、空空的,没加内容的剪切板。

    8a41ce7413171ccd7933dc24d2b0d9dc.png

    现在大家应该知道Windows7电脑剪切板在哪了吧,其实我们只需要借助clipbrd.exe软件来查看,因此大家如果好奇自己剪切板里面是什么内容的话,不妨下载此软件。

    展开全文
  • windows API 剪贴板详解

    千次阅读 2014-05-27 10:32:42
    这都源自于系统中给我们提供了一个暂存数据的存储区域,我们称之为剪 切板,当新的内容送到剪切后,新的内容将会覆盖掉旧的内容,即剪切只能保存一份内容。因为剪切是在内存当中,所以,电脑关闭或者是重启...

    原文出处:http://www.cnblogs.com/cnlyml/archive/2013/03/02/2940434.html 


    剪切、复制、粘贴都是我们在操作电脑的时候经常会用到的功能。但是你知道当我们剪切或者复制的 时候,数据会保存到什么地方吗?当我们粘贴的时候,又是从什么地方将数据输出出来呢?这都源自于系统中给我们提供了一个暂存数据的存储区域,我们称之为剪 切板,当新的内容送到剪切板后,新的内容将会覆盖掉旧的内容,即剪切板只能保存一份内容。因为剪切板是在内存当中,所以,电脑关闭或者是重启以后,存在剪 切板中的内容将会丢失掉。

    除了我们人工的ctrl+C或ctrl+V进行对剪切板的操作以外,我们同时可以使用Windows给我们提供的API来让程序来进行剪切板的复制及粘贴。本篇文章以Visual Studio 2012为编程环境,使用C语言来演示程序操作剪切板的详细教程。


     

    当我们想往剪切板中写入数据时,我们首先需要做的就是打开剪切板:

    Bool OpenClipboard(HWND hWndNewOwner);

    hWndNewOwner参数指定关联到打开剪切板的窗口句柄,传入NULL表示关联到当前任务。每次只允许一个进程打开并访问。当打开后,操作完剪切板以后,就必须要关闭剪切板,因为剪切板每次只能允许一个进程对其进行访问。如果打开剪切板后不关闭,除非程序结束,否则其他进程就无法使用剪切板。


     

    当我们打开剪切板后,需要做的操作便是清空剪切板,在写入剪切板数据之前,我们必须得先清空剪切板,得到剪切板的操控权:

    Bool EmptyClipboard(void)

    当完成以上两个操作以后,我们开始为剪切板分配内存:

    HGLOBAL GlobalAlloc(UINT uFlags, SIZE_T dwBytes);

     第一个参数为分配内存属性,可以是以下内存属性:

     GMEM_FIXED 分配一块固定的内存去续,不允许系统移动,这时返回值是一个指针。
    GMEM_MOVEABLE 分配一块可移动的内存区域,实际上内存块在物理内存中是不可移动的,这里的可移动指的是在应用程序 的默认逻辑堆内可以移动。返回值是内存对象的句柄。可以通过调用GlobalLock()函数讲一个句柄转化为 一个指针,这个标志不能和GMEM_FIXED同时使用。
    GMEM_ZEROINT 初始化内存对象为全0,如果不用这个标志,内存对象将为不确定的内
    GHND GMEM_MOVEABLE和GMEM_ZEROINT联合使用,即可移动同时初始化为0
    GPTR GMEM_FIXED和GMEM_ZEROINT同时使用,即不可移动同时初始化为0

    第二个参数为分配的大小。如果成功则指向该内存,如果失败则返回NULL。

    如果我们分配内存的参数一的内存属性为GMEM_FIXED或GPTR,获得的便是一个指向内存区域的指针,不需要进行锁定内存及解锁内存的操作,直接使用memcpy函数将数据复制到分配的内存区域中即可,如果内存属性为GMEM_MOVEABLE或GHND,获得的便是一块内存区域,我们需要将内存区域转化为一个指针:

    LPVOID GlobalLock(HGLOBAL hMem);

    如果分配内存时分配的内存属性为GMEM_MOVEABLE或GHND,那么就需要锁定内存,锁定由GlobalAlloc分配的内存,并将内存对象的锁定计数器+1。如果该函数成功,则返回内存区域的起始地址指针,失败则返回NULL,GlobalLock会将计数器加1,而GlobalUnlock函数将使计数器减1。对于每次GlobalLock的每一次调用,都必须相应的调用一次GlobalUnlock函数。否则被锁定的内存空间不能够被移动或释放。直到计数器为0时被锁定的内存快才会被移动或者是释放。(更详细的解释请参考MSDN文档:GlobalLock function(Windows))

    如果执行成功,返回的便是内存区域的起始地址指针,我们可以使用memcpy将数据复制到该片内存区域,当执行完毕复制以后,我们需要解除锁定的内存:

     BOOL GlobalUnlock(HGLOBAL hMem);

    参数1为使用分配内存返回的内存区域。


    当内存分配完毕后,便可以将数据写入剪切板了。

    HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);

    参数1为剪切板的数据格式,可以是以下格式:

    CF_TEXT 以NULL结尾的ANSI字符集字符串。它在每行末尾包含一个carriage return和linefeed字符,这是最简单的剪切板数据格式
    CF_OEMTEXT 含有文字数据(与CF_TEXT类似)的内存块。但是它使用的是OEM字符集。
    CF_UNICODETEXT 含有Unicode文字的内存快。与CF_TEXT类似,它在每一行的末尾包含一个carriage return和linefeed字符,以及一个NULL字符(两个0字节)以表示数据结束。CF_UNICODETEXT针对UNICONDE格式
    CF_SYLK 包含Microsoft 「符号连结」数据格式的整体内存块。这种格式用在Microsoft的Multiplan、Chart和Excel程序之间交换数据,它是一种ASCII码格式。
    CF_DIF 包含数据交换格式(DIF)之数据的整体内存块。用于把数据送到VisiCalc电子表格程序中。这也是一种ASCII码格式
    CF_BITMAP 与设备相关的位图格式。位图是通过位图句柄传送给剪贴簿的。
    CF_DIB 定义一个设备无关位图的内存块。
    CF_PALETTE 调色盘句柄。
    CF_METAFILEPICT 以旧的metafile格式存放的「图片」。
    CF_ENHMETAFILE 增强型metafile(32位Windows支持的)句柄。
    CF_PENDATA 与Windows的笔式输入扩充功能联合使用
    CF_WAVE 声音(波形)文件。
    CF_RIFF 使用资源交换文件格式(Resource Interchange File Format)的多媒体数据。
    CF_HDROP 与拖放服务相关的文件列表。

    该数据表使用谷歌自动翻译完成,如果英文较好,可查看MSDN文档:Standard Clipboard Formats(Windows)

    参数2为分配的内存区域。如果执行成功,则返回数据句柄,否则返回NULL。


    当完成对剪切板的操作以后,我们还需要关闭剪切板:

    Bool CloseClipboard(void);

    直接调用该函数便可关闭剪切板,只有执行此函数后,其他进程才能使用剪切板,关闭剪切板后,当前进程就不能写入数据。


     

    如果我们想获取剪切板中数据,可以使用GetClipboardData函数:

    HANDLE GetClipboardData(UINT uFormat);

    参数1为剪切板的数据格式,参见:剪切板的数据格式

    如果执行成功,则返回数据句柄,否则返回NULL。


    下面是代码例程:

    复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <Windows.h>
    
    int main(int argc, char * argv[])
    {
     HGLOBAL hMemory;
     LPTSTR lpMemory;
     char * content = "蓝雨麦郎版权所有";   // 待写入数据
     int contentSize = strlen(content) + 1;
    
     if(!OpenClipboard(NULL))    // 打开剪切板,打开后,其他进程无法访问
     {
      puts("剪切板打开失败");
      return 1;
     }
    
     if(!EmptyClipboard())       // 清空剪切板,写入之前,必须先清空剪切板
     {
      puts("清空剪切板失败");
      CloseClipboard();
      return 1;
     }
    
     if((hMemory = GlobalAlloc(GMEM_MOVEABLE, contentSize)) == NULL)    // 对剪切板分配内存
     {
      puts("内存赋值错误!!!");
      CloseClipboard();
      return 1;
     }
    
     if((lpMemory = (LPTSTR)GlobalLock(hMemory)) == NULL)             // 将内存区域锁定
     {
      puts("锁定内存错误!!!");
      CloseClipboard();
      return 1;
     }
    
     memcpy_s(lpMemory, contentSize, content, contentSize);   // 将数据复制进入内存区域
    
     GlobalUnlock(hMemory);                   // 解除内存锁定
    
     if(SetClipboardData(CF_TEXT, hMemory) == NULL)
     {
      puts("设置剪切板数据失败!!!");
      CloseClipboard();
      return 1;
     }
    
     system("pause");
     return 0;
    }
    复制代码
    转载本文请注明来源:http://www.cnblogs.com/cnlyml。谢谢
    展开全文
  • linux与windows共享剪贴板(clipboard)

    千次阅读 2015-01-20 00:36:00
    linux与windows共享剪贴板(clipboard)的方法 先说两句废话,其实linux和windows之间不需要共享剪贴板,直接在putty中,按住SHIFT+鼠标选择就可以了。 但是作为一种hack行为或者不用鼠标实现复制功能,就需要这种...
  • 2018年12月18日,发明复制粘贴这一伟大功能的女工程师...正是因为复制粘贴太重要了,Windows系统自带的复制粘贴功能根本不够用。比如,我想粘贴倒数第二次复制的内容?比如,批量复制粘贴?再比如,复制粘贴共享?...
  • OLE剪贴板学习心得

    2014-02-10 15:47:13
    OLE剪贴板学习心得 MFC对OLE剪贴板的支持主要集中在两个类上,分别是 COleDataSource,COleDataObject。 其中,COleDataSource作为操作者,而COleDataObject作为消费者,换句话说,用户需要使用COleDataSource把...
  • 使用Visual C++实现OLE剪贴板

    千次阅读 2009-12-29 17:53:00
    ---- 标准的Windows剪贴板是一个被所有Windows应用程序共享的系统服务,因此它并没有自己的句柄或类。但你可以通过CWnd类的成员函数来管理剪贴板。---- 自从OLE(Object Linking and Embedding,对象链接和嵌入)...
  • X11:“剪贴板”如何工作? 如果您在切换到运行X11的东西之前使用过其他操作系统,您会注意到有多个剪贴板: 有时,您可以使用鼠标选择一些文本,切换到另一个窗口,然后点击鼠标中键来粘贴文本。 有时,您可以选择...
  • 剪贴板操作

    2014-04-01 11:00:58
    剪切:系统维护的一个全局公共内存区域.每次只允许一个进程对其进行访问。 剪切操作方法如下:(MSDN上搜索Clipboard Operations) 1.打开剪切 Bool OpenClipboard(HWND hWndNewOwner);
  • 剪贴板所有api函数

    千次阅读 2009-06-26 16:07:00
    剪贴板所有api函数 [转大富翁笔记]这是我在编写剪贴板相关程序是收集的相关API函数。(一)ChangeClipboardChain 将剪贴的连接从一个句柄转到下一个句柄。 BOOL ChangeClipboardChain( HWND hWndRemove, // handle to ...
  • 有没有办法在VI编辑器中将所有行从打开文件复制到剪贴板。 我试图ÿg,但它不使用剪贴板来存储这些行。 那有可能吗?
  • C#中操作系统剪贴板

    2005-01-20 11:01:00
    剪贴板Windows操作系统中最常用的功能之一,它用来从一个应用程序向另一个应用程序传递数据,可以是文本,图象,甚至是程序对象。不过剪贴板也有限制,它在某个特定的时间只能指向一块内容,每一个随后复制的内容...
  • 关于“剪贴板

    2012-01-25 11:55:26
    剪切指windows 操作系统提供的一个暂存数据,并且提供共享的一个模块。也称为数据中转站,剪切在后台起作用,在内存里.,是操作系统设置的一段存储区域,你是在硬盘里找不到的.你只要有文本输入的地方按CRTL+V...
  • 这段代码可以运行于任何映射模式(这里的是设备坐标与逻辑坐标的映射,而非Windows消息映射),只要你在OnPrepareDC()函数中写好相应的映射模式代码。   void CXStitchView::OnEditCopy() {   CRect     rect;...
  • 剪贴板所有api函数

    2009-11-14 16:26:00
    编写剪贴板相关程序是收集的相关API函数。(一)ChangeClipboardChain 将剪贴的连接从一个句柄转到下一个句柄。 BOOL ChangeClipboardChain( HWND hWndRemove, // handle to window to remove HWND hWndNewNext // ...
  • [转贴]C#中操作系统剪贴板

    千次阅读 2005-03-16 01:13:00
    C#中操作系统剪贴板 剪贴板Windows操作系统中最常用的功能之一,它用来从一个应用程序向另一个应用程序传递数据,可以是文本,图象,甚至是程序对象。不过剪贴板也有限制,它在某个特定的时间只能指向一块内容,每...
  • 文章目录查看系统当前的 vim 是否支持剪贴板安装 gvim 来支持系统剪贴板gvim 和 vim 的区别SSH 连接远程主机遇到的问题 查看系统当前的 vim 是否支持剪贴板 首先查看下系统的 vim 是否支持系统剪贴板,在命令终端...
  • 针对 XP 及以前的监视剪贴板更改的方法就不讲了,因为 ...首先,调用AddClipboardFormatListener 函数来向窗口注册监听行为,它需要一个窗口句柄作为传入参数,该句柄所的窗口即是监听剪贴板更新的窗口。 然后,...
  • 常见文本编辑器都会提供剪切来支持复制粘贴,Vim也不例外。 不同的是Vim提供了10类共48个寄存器,提供无与伦比的寄存功能。 最常用的y操作将会拷贝到默认的匿名寄存器中,我们也可以指定具体拷贝到哪个寄存器中。 ...
  • 作为一种基于Windows的开发工具,Delphi支持如下四种数据交换方式:剪贴板、动态数据交换 ( DDE)、对象联接与嵌入(OLE)以及动态联接库(DLLs)。这中间前三种方式最为常用,OLE功能最为强大,DDE次之。而剪贴板使用...
  • windows操作系统中剪切是用来提供暂存数据、提供共享的一个模块。剪切也可以被称为数据中转站,剪切在后台起作用,在内存里,是操作系统设置的一段存储区域,在硬盘里是找不到的。操作系统(Operating System,...
  •  一:使用原生 javascript 中 window.clipboardData 实现复制到剪贴板功能;  二:使用 Zero Clipboard 库; 在尝试了之后发现现有的方案都不能满足需求还有些 bug。方案一仅仅支持 ie 浏览器,在 firefox,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,370
精华内容 4,948
关键字:

windows的剪贴板是指