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

上个月写了个智能注册表定位器,输入一段注册表字符串,能为你打开注册表编辑器并定位到相应的注册表位置,有个哥么说想智能点,当我复制注册表字符串时,给我自动拷贝到输入框去啊,后来就研究了一下剪贴板监控,发现还是蛮简单的,原来这一切,微软都给我们想好了,:-)。

这是智能注册表定位器的外观

首先你要把一个窗口句柄传到windows的剪贴板监听链中,使用API:SetClipboardViewer,这样在用户复制或者剪切时,Windows会给我们的窗口发送一个WM_DRAWCLIPBOARD消息。而且,当有其他程序加入或者退出这个监听者链表时,Windows会给我们的窗口发送一个WM_CHANGECBCHAIN消息。注意:当自己的窗口接收到这两个消息时,应该使用SendMessage函数来把消息传送给下一个监听者。

m_hNextClipboard = ::SetClipboardViewer(GetSafeHwnd());调用该API会返回下一个监听的窗口句柄,这个要保存下来,等下有用。

我下面的说明都是以MFC为例的,SDK里面怎么做,其实是类似的,我就不加说明了,我也没试过,但是原理是一样的。

然后映射两个消息:ON_WM_CHANGECBCHAIN() 和 ON_WM_DRAWCLIPBOARD()

头文件里面添加如下两个消息函数声明:

afx_msg void OnChangeCbChain(HWND hWndRemove, HWND hWndAfter);

afx_msg void OnDrawClipboard();

WM_CHANGECBCHAIN消息的处理,代码如下:

void CTClipboardMonDlg::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter) { CDialog::OnChangeCbChain(hWndRemove, hWndAfter); if (m_hNextClipboard == hWndRemove) m_hNextClipboard = hWndAfter; else if (m_hNextClipboard) ::SendMessage(m_hNextClipboard, WM_CHANGECBCHAIN, (WPARAM)hWndRemove, (LPARAM)hWndAfter); }

当有其他程序加入或者退出windows剪贴板监控链时,你会收到此消息,两个参数hWndRemove正要移出剪贴板监听链的窗口句柄,hWndAfter是移出监听链的窗口句柄的下一个监听窗口句柄,此时你要处理两件事情,如果退出的窗口句柄刚好是当前监听窗口的下一个句柄,则把hWndAfter赋值给m_hNextClipboard,保持整个监听链的联通,如果不是的话则给m_hNextClipboard发送一个相同的WM_CHANGECBCHAIN消息,最终目的也是保持整个监听链的联通性。这是属于一个规范的问题,试想如果有一个程序不这样做,则会造成监听链断裂,某些加入了监听链的窗口就会收不到系统发送的剪贴板消息了(原因是因为系统只给剪贴板链的头发送ON_WM_DRAWCLIPBOARD()消息,然后每个窗口负责给后面剪贴板窗口链上的窗口发送ON_WM_DRAWCLIPBOARD()消息,如果你没有正确处理ON_WM_CHANGECBCHAIN消息,会造成某个窗口不能更新自己的下一个监听链窗口句柄,整个链就断了,链在它之后的窗口就收不到剪贴板变化消息了)。

ON_WM_DRAWCLIPBOARD消息处理,代码如下:

void CTClipboardMonDlg::OnDrawClipboard() { CDialog::OnDrawClipboard(); HGLOBAL hClipboardData; // 如果观看链中在当前程序下面存在下一个程序的话 // 就传递一个WM_DRAWCLIPBOARD 消息给它 if(m_hNextClipboard) ::SendMessage(m_hNextClipboard, WM_DRAWCLIPBOARD, 0, 0); // 打开剪贴板 ::OpenClipboard(GetSafeHwnd()); // 获得剪贴板内容的全局句柄,剪贴板内容格式限制为CF_TEXT 文本格式 hClipboardData = GetClipboardData(CF_TEXT); // 锁定全局句柄的地址,并赋给CString 型变量m_strContent CString m_strContent = (char *)(GlobalLock(hClipboardData)); // 将m_strContent 的内容在编辑框里显示出来 SetDlgItemText(IDC_EDIT_CLIP, m_strContent); // 取消锁定 GlobalUnlock(hClipboardData); // 关闭剪贴板 ::CloseClipboard(); unsigned int anFormats[] = {CF_TEXT, CF_HDROP}; unsigned int nFormat = GetPriorityClipboardFormat(anFormats, sizeof(anFormats)); if(nFormat == CF_TEXT) { HGLOBAL hMem; ::OpenClipboard(GetSafeHwnd()); if(hMem = ::GetClipboardData(CF_TEXT)) { LPTSTR lpszText = (LPTSTR)::GlobalLock(hMem); CString strURL = lpszText; strURL = strURL.SpanExcluding("/r/n"); if(strURL.Left(7).CompareNoCase("http://") == 0 || strURL.Left(6).CompareNoCase("ftp://") == 0 || strURL.Left(7).CompareNoCase("file://") == 0) { //m_pListCtrl->InsertItem(0,lpszText); } ::GlobalUnlock(hMem); } ::CloseClipboard(); } else if (nFormat == CF_HDROP) { HGLOBAL hMem; CString cstrInfo; char szFileName[MAX_PATH]; ::OpenClipboard(GetSafeHwnd()); if(hMem = ::GetClipboardData(CF_HDROP)) { UINT FileNumber = ::DragQueryFile((HDROP)hMem, -1, NULL, 0); //得到文件数量 for (int i = 0; i < FileNumber; i++) { //获得路径及文件名 ::DragQueryFile((HDROP)hMem, i, szFileName, sizeof(szFileName)); cstrInfo = cstrInfo + szFileName; cstrInfo = cstrInfo + "/r/n"; } SetDlgItemText(IDC_EDIT_CLIP, cstrInfo); } ::CloseClipboard(); } }

打开剪贴板,获取数据的方法这里就不说明了,我这里只想强调的是,一定要给监听链上的下一个窗口发送一个相同的ON_WM_DRAWCLIPBOARD消息,否则会怎么样,你可以自己写个程序试试。

在窗口销毁时,应该使这个窗口退出windwos剪贴板监控链,使用API:ChangeClipboardChain,传入调用SetClipboardViewer时的句柄。


附录

源代码下载:

http://download.csdn.net/source/1227140

我在网上找了一些剪贴板的API,可以去查查MSDN,嘿嘿,你想监控啥类型的数据就自己去编程实现啦。

(一)ChangeClipboardChain
将剪贴的连接从一个句柄转到下一个句柄。
BOOL ChangeClipboardChain(
HWND hWndRemove, // handle to window to remove
HWND hWndNewNext // handle to next window
);
(1)hWndRemove表示第一个窗口的句柄(断开)。
(2)hWndNewNext表示第二个窗口的句柄(连接)。
注意,在使用之前应该使用SetClipboardViewer事先进行窗口句柄的连接。
(二)CloseClipboard
关闭剪贴板。
BOOL CloseClipboard(VOID)//VOID意思是空白。
本函数没有参数,事先应该用OpenClipboard函数打开过剪贴板。
(三)CountClipboardFormats
不管剪贴板是什么格式,全部转化为数据格式。
int CountClipboardFormats(VOID)
本函数没有参数。
(四)EmptyClipboard
清空剪贴板。
BOOL EmptyClipboard(VOID)
本函数没有参数。
(五)EnumClipboardFormats
使剪贴板内的格式转变成指定格式。
UINT EnumClipboardFormats(
UINT format // specifies a known available clipboard format
);
其中format表示的是将要转化成的格式。该参数的意义可参照后面。
(六)GetClipboardData
获取剪贴板内的数据。
HANDLE GetClipboardData(
UINT uFormat // clipboard format
);
其中format表示的是剪贴板内数据的格式。该参数的意义可参照后面。
(七)GetClipboardFormatName
获取剪贴板内数据格式的名称。
int GetClipboardFormatName(
UINT format, // clipboard format to retrieve
LPTSTR lpszFormatName, // address of buffer for name
int cchMaxCount // length of name string in characters
);
(1)format表示的意义同前,应该是不事先规定格式;
(2)lpszFormatName表示的是格式名称地址;
(3)cchMaxCount剪贴板内数据的长度。
(八)GetClipboardOwner
获取当前剪贴板是属于哪一个窗口的句柄。
HWND GetClipboardOwner(VOID)
返回那个窗口的句柄。
(九)GetClipboardSequenceNumber
返回剪贴板序号。
DWORD GetClipboardSequenceNumber(VOID)
(十)GetClipboardViewer
返回剪贴板属于窗口的句柄。
HWND GetClipboardViewer(VOID)
(十一)GetOpenClipboardWindow
返回打开剪贴板的那个窗口句柄。
HWND GetOpenClipboardWindow(VOID)
(十二)GetPriorityClipboardFormat
int GetPriorityClipboardFormat(
UINT *paFormatPriorityList, // address of priority list
int cFormats // number of entries in list
);
(十三)IsClipboardFormatAvailable
判断剪贴板的格式。
BOOL IsClipboardFormatAvailable(
UINT format // clipboard format
);
其中format表示的是剪贴板内数据的格式。该参数的意义可参照后面。
(十四)OpenClipboard
打开剪贴板。
BOOL OpenClipboard(
HWND hWndNewOwner // handle to window opening clipboard
);
返回剪贴板的句柄。
(十五)RegisterClipboardFormat
注册新的剪贴板格式。
UINT RegisterClipboardFormat(
LPCTSTR lpszFormat // address of name string
);
lpszFormat新的剪贴板格式名称。
(十六)SetClipboardData
设置剪贴板内的数据。
HANDLE SetClipboardData(
UINT uFormat, // clipboard format
HANDLE hMem // data handle
);
uFormat表示的是要放进剪贴板数据的格式;
hMem表示数据的地址指针。
(十七)SetClipboardViewer
将剪贴板内容连接到窗口。
HWND SetClipboardViewer(
HWND hWndNewViewer // handle to clipboard viewer window
);
hWndNewViewer表示要连接到的那个窗口句柄。
上文中剪贴板格式Format的可选参数如下:
CF_BITMAP位图格式;
CF_DIB
CF_DIBV5
CF_DIF
CF_DSPBITMAP
CF_DSPENHMETAFILE
CF_DSPMETAFILEPICT
CF_DSPTEXT
CF_ENHMETAFILE
CF_GDIOBJFIRST
CF_GDIOBJLAST
CF_HDROP
CF_LOCALE
CF_METAFILEPICT
CF_OEMTEXT
CF_OWNERDISPLAY
CF_PALETTE
CF_PENDATA
CF_PRIVATEFIRST
CF_PRIVATELAST
CF_RIFF
CF_SYLK
CF_TEXT文本格式;
CF_WAVE音乐格式;
CF_TIFF
CF_UNICODETEXT

【END】

windows 剪贴板监控相关推荐

  1. Win32编程实现剪贴板监控查看

    网络上有很多使用MFC和.NET实现windows剪贴板监控的程序.这里参考<Windows程序设计(第五版)>实现了一个最简单的Win32剪贴板监控程序.采用原始的win32编程,不适用 ...

  2. Windows性能计数器监控实践

    Windows性能计数器(Performance Counter)是Windows提供的一种系统功能,它能实时采集.分析系统内的应用程序.服务.驱动程序等的性能数据,以此来分析系统的瓶颈.监控组件的表 ...

  3. 用Spotlight on windows 实时监控Windows服务器性能

    用Spotlight on windows 实时监控Windows服务器性能 2010-02-03 10:30:25|  分类: else |  标签: |字号大中小 订阅 用Spotlight on ...

  4. 怎样将GIS图形复制到Windows剪贴板,粘贴到Word中

    很久没写随笔了,有点想关了这个博客,不再更新,但还是没有下定决心.趁这些天比较闲,发一个以前写着玩的功能吧.     复制.粘贴功能是一件很简单的事情,但怎样将GIS图形粘贴到word中呢?最简单的思 ...

  5. github windows系统监控_你需要的:Windows | 精品软件集

    本页主要展示Windows精品软件,同类产品尽量做到只展示一个如有好的软件可在本页底部回复,推荐给其他小伙伴文章目录 1 效率工具类 2 制作处理 3 文本编辑类 4 媒体播放类 5 下载类 6 截图 ...

  6. windows 进程监控 Procmon.exe

    windows 进程监控 Procmon.exe window下一个程序打开太慢,可以用此程序监控.在哪一步慢了,读取文件还是注册表. ProcessMonitor3.2 Process Monito ...

  7. 深聊性能测试,从入门到放弃之: Windows系统性能监控(三)任务管理器介绍及使用。

    任务管理器 1.引言 2.任务管理器 2.1 打开方式 2.2 介绍 2.2.1 定义 2.2.2 进程 2.2.3 性能 2.2.4 应用历史记录 2.2.5 启动 2.2.6 用户 2.2.7 详 ...

  8. C#从windows剪贴板粘贴内容的代码

    下边内容是关于C#从windows剪贴板粘贴内容的内容,应该对各位也有用途. using System; using System.Drawing; using System.Collections; ...

  9. 深聊性能测试,从入门到放弃之: Windows系统性能监控(一) 性能监视器介绍及使用。

    性能监视器介绍及使用 1.引言 2.性能监视器 2.1 打开方式 2.2 基本介绍 2.3 计数器介绍 2.3.1 处理器性能计数器 2.3.2 内存性能计数器 2.3.3 网络性能计数器 2.4 创 ...

最新文章

  1. Oracle 存储结构_表空间简介
  2. 【原创】MapReduce编程系列之表连接
  3. 用TensorFlow的Linear/DNNRegrressor预测数据
  4. ASP.NET Core WebAPI控制器返回类型的最佳选项
  5. 邮件作为证据如何提交_电子邮件如何取证、举证?
  6. L2-012. 关于堆的判断-PAT团体程序设计天梯赛GPLT
  7. spring boot 2.0之安全
  8. JavaScript计时
  9. 海思Hi3519AV100 emmc flash方式 linux系统移植 hitool工具烧写
  10. Android系统在超级终端下必会的命令大全(adb shell命令大全)
  11. 双线性映射matlab,[Matlab]双线性变换法设计数字带通滤波器
  12. OA系统新流程创建与管理办法
  13. navicat连接mysql1205报错
  14. Excel日期按秒自增公式
  15. 请登录游戏大厅进行签到
  16. 亲测可用:两个在线的测试数据生成工具
  17. 通信加密和解密,公钥,私钥,CA
  18. 斐波那契数列----有一段楼梯有n级台阶,规定每一步只能跨一级或两级,要登上第n级台阶有几种不同的走法?...
  19. Deep Domain Confusion: Maximizing for Domain Invariance
  20. 航空专家:中国北斗系统与美国GPS相比存3大难点

热门文章

  1. 2023年京东炸年兽脚本《京东炸年兽活动脚本》
  2. 如何在CSDN博客栏目中添加“给我写信”
  3. Windows 10创建用户
  4. SP 2022论文泛读
  5. 聊聊我当面试官的感受吧
  6. 股份有限公司按规定注销库存股时,对被注销库存股的账面余额超过面值总额的部分
  7. Macos 安装MacTex SublimeText3 Skim环境
  8. win7、win10关闭驱动签名,进入驱动测试模式,以及常见初级问题的解决
  9. 开发技巧--发送手机验证码接口调用
  10. 水逆了一整年的王源,2020年年初能靠《大主宰》翻身吗?