C++ 监听剪贴板变化
前言
对于 C++ 中实现监听剪贴板的功能,有以下两种方式
01 Clipboard Viewer
使用 SetClipboardViewer 将指定窗口添加到剪贴板查看器链,此函数用于向后兼容早期版本的 Windows。(不推荐)
属于剪贴板查看器链的窗口(称为剪贴板查看器窗口)必须通过接收 WM_CHANGECBCHAIN 和 WM_DRAWCLIPBOARD 处理剪贴板消息。每个剪贴板查看器窗口调用 SendMessage 函数,以将这些消息传递到剪贴板查看器链中的下一个窗口。
剪贴板查看器窗口退出时,必须通过调用 ChangeClipboardChain 函数(例如,响应 WM_DESTROY 消息)从剪贴板查看器链中删除自身。
SetClipboardViewer 函数的存在可提供与早期版本的 Windows 的向后兼容性。无法正确处理剪贴板链消息的应用程序可能会破坏剪贴板查看器链。
02 Clipboard Format Listener
推荐使用本方法
将窗口添加到剪贴板格式侦听器列表后,每当剪贴板的内容发生更改时,该窗口将发布 WM_CLIPBOARDUPDATE 消息。
代码实现
我这里使用上述第二种方法进行实现。
在窗口创建时,使用 AddClipboardFormatListener
注册剪贴板格式侦听器(为了保持兼容性,我这边使用了动态加载函数):
case WM_CREATE:
{
// 动态加载 监听剪切板数据
HINSTANCE hUser32 = LoadLibraryW(L"User32.dll");
if (hUser32)
{
typedef BOOL(WINAPI * LPAddClipboardFormatListener)(HWND);
LPAddClipboardFormatListener AddClipboardFormatListener = (LPAddClipboardFormatListener)GetProcAddress(hUser32, "AddClipboardFormatListener");
if (AddClipboardFormatListener)
{
if (!AddClipboardFormatListener(hWnd))
{
MessageBoxW(NULL, L"Error Add Clipboard listener", L"ERROR", MB_OK);
}
}
FreeLibrary(hUser32);
}
break;
}
窗口销毁时记得移除(为了保持兼容性,我这边使用了动态加载函数):
case WM_DESTROY:
{
// 动态加载 移除监听剪切板数据
HINSTANCE hUser32 = LoadLibraryW(L"User32.dll");
if (hUser32)
{
typedef BOOL(WINAPI * LPRemoveClipboardFormatListener)(HWND);
LPRemoveClipboardFormatListener RemoveClipboardFormatListener = (LPRemoveClipboardFormatListener)GetProcAddress(hUser32, "RemoveClipboardFormatListener");
if (RemoveClipboardFormatListener)
{
if (!RemoveClipboardFormatListener(hWnd))
{
MessageBoxW(NULL, L"Error Remove Clipboard listener", L"ERROR", MB_OK);
}
}
FreeLibrary(hUser32);
}
PostQuitMessage(0);
break;
}
对于剪贴板数据的处理,我们需要响应 WM_CLIPBOARDUPDATE
消息:
case WM_CLIPBOARDUPDATE:
{
// 无法打开剪贴板
if (!OpenClipboard(NULL))
{
break;
}
HANDLE hData = GetClipboardData(CF_TEXT);
// 无法获取数据
if (hData == NULL)
{
CloseClipboard();
break;
}
char *pszText = static_cast<char *>(GlobalLock(hData));
if (pszText == NULL)
{
GlobalUnlock(hData);
CloseClipboard();
break;
}
// TODO: 在这里添加你的处理代码
GlobalUnlock(hData);
CloseClipboard();
break;
}
吐槽
我只能说,网上都没有什么相关资料,我研究了半天才搞明白怎么监听剪贴板。
我研究这个的主要目的是为了写一个程序自动监听并格式化剪贴板,方便我上课复制老师PPT记笔记。
参考资料:
- SetClipboardViewer 函数 https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-setclipboardviewer
- AddClipboardFormatListener 函数 https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-addclipboardformatlistener
评论区