比较保存在剪贴板中的数据

时间:2011-02-12 16:14:12

标签: c# clipboard

我正在使用code in this thread to catch the Clipboard changes

究竟是什么,或者代码正在做什么,为我的应用程序注册一个剪贴板查看器,以便能够捕获所做的所有剪贴板更改。

一旦剪贴板改变,WndProc将触发并运行OnClipboardChanged()函数..

我通过使用键盘快捷键(Ctrl + C)

复制visual studio中的文本

当我从Visual Studi复制时,数据将被粘贴两次,这意味着WM_DRAWCLIPBOARD被调用两次?(请检查代码)

如何检查或停止此行为?

我只是想确保粘贴的数据不会重复。?

2 个答案:

答案 0 :(得分:0)

您可以存储正在复制的数据的哈希码,并查看最后一个匹配的数据。这是一个未经测试的文本数据对象示例:

        IDataObject iData = Clipboard.GetDataObject();

        Int hash = iData != null ? iData.GetData(DataFormats.Text).GetHashCode() : 0;

        if (ClipboardChanged != null && hash != lastHash)
        {
            ClipboardChanged(this, new ClipboardChangedEventArgs(iData));
            lastHash = hash;
        }

我不确定最好的方法一般来说,你总是可以使用GetFormats()并检索所有格式+哈希对并使用它们进行查找,因为我不确定不能是不同格式的冲突。

答案 1 :(得分:0)

我知道这是ClipboardChain中的某个已知错误。你可以简单地对这种行为做的是过滤那些伪调用。我只是在检查呼叫之间的时间跨度是否为人。在这里:

    DateTime dtLastChangedNotify = DateTime.MinValue;
    TimeSpan tsHumanReactionTime = TimeSpan.FromMilliseconds(100);
    private void MessageProc(IntPtr hwnd, int Msg, IntPtr WParam, IntPtr LParam, ref bool handled)
    {
        if (Msg == WM_CHANGECBCHAIN)
        {
            if (WParam == _nextCBWatcher)
            {
                _nextCBWatcher = LParam;
            }
            else
            {
                SendMessage(_nextCBWatcher, Msg, WParam, LParam);
            }
        }
        else if (Msg == WM_DRAWCLIPBOARD)
        {
            uint cpid = 0, pid = 0;

            if (_wasReset)
            {
                _wasReset = false;
                return;
            }

            GetWindowThreadProcessId(GetClipboardOwner(), out pid);
            cpid = GetCurrentProcessId();

            // i only want info about what is copied by other programs.
            if (pid != cpid)
            {
                // filter no human calls.
                if ((DateTime.Now - dtLastChangedNotify) > tsHumanReactionTime)
                {
                    OnClipboardChange();
                    dtLastChangedNotify = DateTime.Now;
                }
            }

            SendMessage(_nextCBWatcher, Msg, WParam, LParam);
        }
        else if (Msg == WM_DESTROY)
        {
            ChangeClipboardChain(_ownerWnd, _nextCBWatcher);
        }
    }