上位机MFC监控剪切板与数据提取实例
上位机MFC监控剪切板与数据提取实例
使用过迅雷或者旋风的朋友都有经历过这样情景,复制一下载URL后,程序会弹出下载窗口。
其实软件也就是添加有剪切板监视功能。
当剪切板内数据发生变化后,系统会向程序发送剪切板数据发生变化的消息。
程序进而 提取剪切板内容,进行判断,实现特定功能。
当前例程也实现剪切板监视功能。
0.创建基于对话框应用程序,类名CClipboardMonitor;生成对话框类CClipboardMonitorDlg;
1.添加编辑框IDC_EDIT1,与按钮<开始监控剪切板>,<停止监控剪切板>并添加其点击函数
- void CClipboardMonitorDlg::OnBnClickedButton1()//开始监控剪切板;
- {
- m_hNextClipboard = this->SetClipboardViewer();
- }
- void CClipboardMonitorDlg::OnBnClickedButton2()//停止监控剪切板;
- {
- ChangeClipboardChain(m_hNextClipboard);
- }
复制代码 函数中变量m_hNextClipboard为 HWND m_hNextClipboard;//保存剪切板链中下一窗口句柄;作用如注释
两个函数分别实现开始与停止监视剪切板功能。
2.当有向系统添加新的监视窗口后,系统会触发消息WM_CHANGECBCHAIN。
通过类向导添加WM_CHANGECBCHAIN处理函数
void CClipboardMonitorDlg::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter)
{
CDialogEx::OnChangeCbChain(hWndRemove, hWndAfter);
/*
说明:
WINDOWS系统维护一个剪贴板监听链,链中节点为窗口句柄,
通过函数SetClipboardViewer可以将一个窗口加入此链。
当有其他程序加入或退出窗口剪贴板监控链时,
系统会向链发送WM_CHANGECBCHAIN消息,也就是会触发此函数。
此函数参数:hWndRemove为正要移出剪贴板监听链的窗口句柄,
hWndAfter为移出监听链的窗口句柄的下一个监听窗口句柄,
此时函数中要处理两件事情,如果退出的窗口句柄刚好是当前监听窗口的下一个句柄,
则把hWndAfter赋值给成员变量m_hNextClipboard,保证整个监听链的联通,
如果不是的话则给m_hNextClipboard发送一个相同的WM_CHANGECBCHAIN消息,
最终目的也是保持整个监听链的联通性。这是属于一个规范的问题,
试想如果有一个程序不这样做,则会造成监听链断裂,
某些加入了监听链的窗口就会收不到系统发送的剪贴板消息.
原因是因为系统只给剪贴板链的头发送WM_DRAWCLIPBOARD消息,
然后每个窗口负责给后面剪贴板窗口链上的窗口发送WM_DRAWCLIPBOARD消息,
如果没有正确处理WM_CHANGECBCHAIN消息,
会造成某个窗口不能更新自己的下一个监听链窗口句柄,
整个链就断了,链在它之后的窗口就收不到剪贴板变化消息。
*/
if (m_hNextClipboard == hWndRemove)
m_hNextClipboard = hWndAfter;
else if (m_hNextClipboard)
::SendMessage(m_hNextClipboard, WM_CHANGECBCHAIN, (WPARAM)hWndRemove, (LPARAM)hWndAfter);
}
3.当剪切板内容发生变化时会触发消息WM_DRAWCLIPBOARD。通过类向导添加WM_DRAWCLIPBOARD处理函数
- void CClipboardMonitorDlg::OnDrawClipboard()
- {
- CDialogEx::OnDrawClipboard();
- /*
- 如果链中在当前程序下面存在下一个程序的话
- 就向下传递一个WM_DRAWCLIPBOARD 消息。
- */
- if(m_hNextClipboard)
- ::SendMessage(m_hNextClipboard, WM_DRAWCLIPBOARD, 0, 0);
- /**/
- HGLOBAL hClipboardData;
- ::OpenClipboard(GetSafeHwnd());// 打开剪贴板
- // 获得剪贴板内容的全局句柄,剪贴板内容格式默认为CF_TEXT 文本格式;
- hClipboardData = GetClipboardData(CF_TEXT);
- CString sData = (char *)(GlobalLock(hClipboardData));
- SetDlgItemText(IDC_EDIT1, sData);
- GlobalUnlock(hClipboardData);// 取消锁定
- ::CloseClipboard();// 关闭剪贴板
-
- /*提取剪切板URL测试
- unsigned int nFormats[] = {CF_TEXT, CF_HDROP};
- unsigned int nFormat = GetPriorityClipboardFormat(nFormats, sizeof(nFormats)/sizeof(int) );
- if(nFormat == CF_TEXT)
- {
- HGLOBAL hMem;
- ::OpenClipboard(GetSafeHwnd());
- if(hMem = ::GetClipboardData(CF_TEXT))
- {
- LPTSTR lpszText = (LPTSTR)::GlobalLock(hMem);
- CString sURL = lpszText;
- sURL.TrimLeft();
- if(sURL.Left(7).CompareNoCase("http://") == 0 ||
- sURL.Left(8).CompareNoCase("https://") == 0 ||
- sURL.Left(6).CompareNoCase("ftp://") == 0 ||
- sURL.Left(7).CompareNoCase("file://") == 0)
- {
- SetDlgItemText(IDC_EDIT1, sURL);//显示提取的URL
- }
- ::GlobalUnlock(hMem);
- }
- ::CloseClipboard();
- }
- else if (nFormat == CF_HDROP)
- {
- }
- */
- }
复制代码 此函数实现将剪切板中的数据显示在编辑框中。
屏蔽的代码实现从剪切板提取URL,并显示在编辑框中。
例程使用的是较老的方法实现剪切板监视与数据提取。后一例程提供 新的方法;
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|