侧边栏壁纸
  • 累计撰写 25 篇文章
  • 累计创建 11 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

C++ 监听剪贴板变化

LinJHS
2024-03-18 / 0 评论 / 0 点赞 / 79 阅读 / 4675 字 / 正在检测是否收录...

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记笔记。


参考资料:

  1. SetClipboardViewer 函数 https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-setclipboardviewer
  2. AddClipboardFormatListener 函数 https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-addclipboardformatlistener
0

评论区