实现网络蚂蚁的实时监视剪贴板功能

原创 2003年01月20日 09:43:00

实现网络蚂蚁的实时监视剪贴板功能
                                                      作者:黑龙江省五大连池   马明臣  
 我们知道,网络蚂蚁能够实时地监视剪贴板,如果我们能够在自己的程序中实现这个功能,肯定为我们的程序增色不少。
 那它到底是如何实现的呢?我们可以想到的最简单的方法是,直接开个计时器,定时检查剪贴板上的内容,或者另写个线程来检查。这两个方法都能够监视剪贴板,但遗憾的是实时性太差,又占用了系统的大量资源,很不合算。好一点的方法可以用Win32API中关于剪贴板钩子(HOOK)的函数,只要安装了剪贴板的钩子函数,就可以做到实时地监视剪贴板,因为任何剪贴板的改变都会触发一条消息,而钩子函数拦截了这条信息。然而,这要求当前程序必须要有机会获得CPU控制权才能处理这个消息。如果该程序这时并没有释放CPU,监视剪贴板的程序并不能处理消息。只有当该程序执行完了之后,别的程序才能获得处理机会,但此时,剪贴板只剩下最后一次粘贴的内容了。而且,使用钩子函数非常危险,一旦你的程序出了问题,整个系统也就跟着瘫痪了。
既然这些方法都不太理想,那我们不妨转换一下思维,不再去管剪贴板,而想想如何让剪贴板直接向自己的程序发消息,这样肯定能做到百分之百的实时。为此我仔细的查看了各种Windows的编程资料,结果是:因为剪贴板不具有自己的句柄(Handle),它本身也不是Windows的一个类,故剪贴板是不会自己发消息的。但是系统是如何能够接收剪切/拷贝到剪贴板等命令呢?也即是如何接收WM_COPY和WM_CUT,WM_PASTE等消息呢?经过研究发现能够发送消息的是剪贴板查看器,原来多个剪贴板查看器依次连接成剪贴板查看链。因此,要实现实时监视剪贴板必须将自己的程序注册成为剪贴板查看器(即加入链表中)。下面笔者以C++ Builder 5.0为例编程说明其具体实现过程。
首先新建一个工程,在Form1上增加一个Memo控件,然后在Form1的.h里面加上#include <vcl/Clipbrd.hpp>,因为下面要用到的API函数大多是在该头文件中定义的。
在Form1的.h的public加上:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DRAWCLIPBOARD,TMessage,ClipboardChanged) //映射这个消息
END_MESSAGE_MAP(TForm)
HWND LastHandle;// 用于保存剪贴板查看器链中下一个窗口的句柄。
 接下来,当然是把自己的程序窗口注册成为剪贴板查看器了。在Form1的OnCreate事件中加入一句:
 LastHandle=SetClipboardViewer(Form1->Handle);
 该函数会将指定的窗口加入剪贴板查看器链,参数handle就是你欲新加入的窗口的句柄,返回值则为系统的剪贴板查看器链中下一个窗口的句柄。
 当你自己的程序退出时,必须从剪贴板查看器链中删除本窗口。在Form1的OnClose事件中加入两句:
ChangeClipboardChain(Form1->Handle,LastHandle);
 函数ChangeClipboardChain是SetClipboardViewer的逆操作,能将第一个参数handle指定的窗口从剪贴板查看器链中删除,第二个参数是剪贴板查看器链中下一个窗口的句柄,是供系统调整剪贴板查看器链表用的,我们不用管它。
 最后一步,也是最关键的一步,如果剪贴板内容有变化,窗口将自动激活 WM_DRAWCLIPBOARD消息,也即间接地实现了让剪贴板向自己的程序发消息的功能,这就能够实时监视剪贴板,相信网络蚂蚁也应该是用这个方法。有一点要注意的是,在接收处理WM_DRAWCLIPBOARD消息时要将消息传递给剪贴板查看链中的下一个窗口,以便让其它程序也能监视剪贴板,因为该消息只直接发给链中的第一个程序,其他程序不会直接收到该消息。
 程序如下,在Form1的.h的private加上:
void __fastcall ClipboardChanged(TMessage& Msg);
 再编写自己的处理过程,这就是你自由发挥的地方了。本例设为自动将剪贴板的文本粘贴到Memo控件中。
 在Form1的.cpp内加上:
void __fastcall TForm1::ClipboardChanged(TMessage& Msg)
{
 if (Clipboard()->HasFormat(CF_TEXT))
    Memo1->Text = Clipboard()->AsText;
 }    
 这一过程中使用了 TClipboard 类的 Clipboard 函数获取剪贴板内文本内容,至于如何获取剪贴板内的其它非文本类型的内容则不在本文讨论范围内了,读者可自己在C++ Builder中输入TClipboard ,再按F1,键,就可以看到各个函数的详细用法了,不过这些帮助可都是英文的呀!
以上程序在C++ Builder 5.0+PWIN98系统下调试通过,由于笔者水平有限,上文如有不妥之处,请大家与我一起探讨。

 

APIHOOK实现剪贴板的控制

本人也是刚刚接触APIHook,写的也是入门的程序,希望本文对初学APIHook的人有所帮助。   文章之前先介绍下要利用的库Detours,这是微软提供的APIHook的库,具体的可以到网上查找。里...
  • reeves1576
  • reeves1576
  • 2008年02月21日 15:32
  • 560

c#实现Windows剪贴板监视器

Windows剪贴板剪贴板(ClipBoard)是内存中的一块区域,是Windows内置的一个非常有用的工具,通过小小的剪贴板,架起了一座彩桥,使得在各种应用程序之间,传递和共享信息成为可能。然而美中...
  • testcs_dn
  • testcs_dn
  • 2015年01月03日 18:18
  • 6828

windows 剪贴板监控

迅雷下载或者旋风下载都有一个很有意思的剪贴板监控功能,当你打开剪贴板监控时,如果你复制了一个下载的URL,这两个程序都会弹出来下载框来让你去下载,显得很智能,昨天发现灵格斯词霸也有个剪贴板取词功能。上...
  • magictong
  • magictong
  • 2009年04月19日 18:53
  • 11715

在C#中监视剪贴板的变化

http://www.developer.com/net/csharp/article.php/3359891#overview
  • changhu
  • changhu
  • 2011年02月20日 17:23
  • 441

剪贴板监控--C++实现

给大家两个消息,happy的去玩吧:WM_CHANGECBCHAIN 和 WM_DRAWCLIPBOARD。。 原理:剪贴板有一个监控链表,这个链表中就是监控了剪贴板的程序,如果有新的监控程序加入或...
  • keep_moving_cqu
  • keep_moving_cqu
  • 2013年08月19日 11:05
  • 1702

WIN7下使用.net(C#)监视剪贴板

最近需要做一个小程序,需要常驻后台,监视剪贴板变化并提取内容, 在网上查了一些资料,先采用SetClipboardViewer方法实现,具体原理可以参考http://www.cnblogs.com/...
  • rrrrssss00
  • rrrrssss00
  • 2012年04月06日 09:16
  • 5172

如何监视系统剪贴板变化?

        今天在上网时,复制了一个数据,可是因为其他事情忘记粘贴了,后来就找不到了,所以想到做一个监视系统剪贴板变化的程序,然后把内容放到一个RIchtextbox中,可是我不知道应该如何监视系...
  • myg2006
  • myg2006
  • 2006年08月02日 13:27
  • 1023

VC++语言实现MFC剪贴板操作实例代码

本文主要介绍了VC++语句语言/MFC中如下内容的剪贴板操作: 1、文本内容的操作 2、WMF数据的操作 3、位图的操作 4、设置应用自定义各式 5、感知剪贴板内容的改变 6、自动将数...
  • yongzhen150
  • yongzhen150
  • 2014年12月23日 10:54
  • 740

纯js实现复制到剪贴板功能

纯js实现复制到剪贴板功能 在网页上复制文本到剪切板,一般是使用JS+Flash结合的方法,网上有很多相关文章介绍。随着 HTML5 技术的发展,Flash 已经在很多场合不适用了,...
  • lhw413
  • lhw413
  • 2017年05月07日 21:46
  • 1154

在应用程序中监视剪贴板的变化和内容

在应用程序中监视剪贴板的变化和内容stove@vip.sina.com 剪贴板是Windows中系统级的堆空间,系统中任何一个应用程序对剪贴板都有访问权,可以通过剪贴板消息和使用剪贴板API来读写剪贴...
  • stovezhang
  • stovezhang
  • 2003年05月08日 14:18
  • 665
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现网络蚂蚁的实时监视剪贴板功能
举报原因:
原因补充:

(最多只允许输入30个字)