首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >监控剪贴板

监控剪贴板
EN

Stack Overflow用户
提问于 2013-08-19 10:13:33
回答 1查看 3.1K关注 0票数 0

我正在用全局钩子写入dll。其中一项任务是在执行复制操作时查看剪贴板并从剪贴板中删除所有数据。下面是窗口的回调函数:

代码语言:javascript
复制
string test("my data");

LRESULT CALLBACK WndHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
        case WM_CREATE:
            nextClipboardViewer = SetClipboardViewer(windowHandler);
            MessageBeep(MB_ICONINFORMATION);
            break;
        case WM_CHANGECBCHAIN:
            if((HWND) wParam == nextClipboardViewer) 
                nextClipboardViewer == (HWND) lParam;
            else if(nextClipboardViewer != NULL)
                SendMessage(nextClipboardViewer, msg, wParam, lParam);
            break;
        case WM_DRAWCLIPBOARD:
            if(OpenClipboard(windowHandler)) {
                EmptyClipboard();
                HGLOBAL hClipboardData;
                hClipboardData = GlobalAlloc(GMEM_MOVEABLE, test.size() + 1);
                char * pchData;
                pchData = (char*)GlobalLock(hClipboardData);
                memcpy(pchData, test.c_str(), test.size() + 1);
                GlobalUnlock(hClipboardData);
                SetClipboardData(CF_TEXT, hClipboardData);
                CloseClipboard();
            }
            SendMessage(nextClipboardViewer, msg, wParam, lParam);
            break;
        case WM_DESTROY:
            ChangeClipboardChain(windowHandler, nextClipboardViewer);
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
            break;
    }
    return 0;
}

我只是尝试在剪贴板中替换信息,但这段代码不起作用。

更新:现在我正在使用不可见窗口和SetClipboardViewer来监视更改。但是剪贴板中的数据不会改变。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-19 19:59:11

我怀疑在处理WM_DRAWCLIPBOARD消息时更改剪贴板的内容是否真的安全--至少我很惊讶您没有触发无限循环(因为对EmptyClipboard()SetClipboardData()的调用可能会触发另一条WM_DRAWCLIPBOARD消息)。也许这个系统对此有保护--我从来没有想过要找出--但它还是感觉不对:)

试试这个版本,其中:

  1. 将剪贴板更新移动到一个单独的消息,该消息由窗口提交给自己(将它移到剪贴板之外,会更改通知代码)
  2. 使用全局标志来忽略它自己所做的更改。

注意:我认为您的代码的实际错误是在处理WM_CREATE时,还没有分配windowHandler。您大概是将其设置为CreateWindowEx返回的值,但在处理WM_CREATE时,CreateWindowEx实际上还没有返回。这意味着剪贴板查看器从未真正正确地建立起来。我已经更改了引用,以使用hwnd来修复这个问题。

代码语言:javascript
复制
string test("my data");

#define MSG_UPDATECLIPBOARD     (WM_APP + 1)
static bool g_fIgnoreClipboardChange = false;

LRESULT CALLBACK WndHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
    case WM_CREATE:
        nextClipboardViewer = SetClipboardViewer(hwnd);
        MessageBeep(MB_ICONINFORMATION);
        break;
    case WM_CHANGECBCHAIN:
        if((HWND) wParam == nextClipboardViewer) 
            nextClipboardViewer = (HWND) lParam;
        else if(nextClipboardViewer != NULL)
            SendMessage(nextClipboardViewer, msg, wParam, lParam);
        break;
    case WM_DRAWCLIPBOARD:
        if (!g_fIgnoreClipboardChange)
            PostMessage(hwnd, MSG_UPDATECLIPBOARD, 0, 0);
        if(nextClipboardViewer != NULL)
            SendMessage(nextClipboardViewer, msg, wParam, lParam);
        break;
    case MSG_UPDATECLIPBOARD:
        g_fIgnoreClipboardChange = true;
        if(OpenClipboard(hwnd)) {
            HGLOBAL hClipboardData;
            hClipboardData = GlobalAlloc(GMEM_MOVEABLE, test.size() + 1);
            char * pchData;
            pchData = (char*)GlobalLock(hClipboardData);
            memcpy(pchData, test.c_str(), test.size() + 1);
            GlobalUnlock(hClipboardData);
            SetClipboardData(CF_TEXT, hClipboardData);
            CloseClipboard();
        }
        g_fIgnoreClipboardChange = false;
        break;      
    case WM_DESTROY:
        ChangeClipboardChain(hwnd, nextClipboardViewer);
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
        break;
    }
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18311274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档