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

C# 比较保存在剪贴板中的数据,c#,clipboard,C#,Clipboard,我在用电脑 我所做的或代码所做的就是,为我的应用程序注册一个剪贴簿查看器,以便能够捕获所有对剪贴板所做的更改 剪贴板更改后,WndProc将启动并运行OnClipboardChanged()函数 iam使用键盘快捷键(Ctrl+C)从visual studio复制文本作为示例 当我从Visual Studi复制时,数据将粘贴两次,这意味着WM_DRAWCLIPBOARD将被调用两次?(请检查代码) 如何检查或阻止这种行为 我只是想确保粘贴的数据不会重复。?您可以存储要复制的数据的哈希代码,并查看

我在用电脑

我所做的或代码所做的就是,为我的应用程序注册一个剪贴簿查看器,以便能够捕获所有对剪贴板所做的更改

剪贴板更改后,WndProc将启动并运行OnClipboardChanged()函数

iam使用键盘快捷键(Ctrl+C)从visual studio复制文本作为示例

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

如何检查或阻止这种行为


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

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

        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()
检索所有格式+散列对并使用它们进行查找,因为我不确定不同格式之间是否存在冲突。

我知道这是剪贴簿链中的某个已知错误。针对这种行为,您可以简单地过滤这些伪调用。我只是在检查两次通话之间的时间间隔是否是人为的。下面是:

    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);
        }
    }

不确定为什么要调用两次,但您始终可以使用布尔值进行检查。请编辑您的问题,以包括从应用程序复制文本时所采取的确切步骤。您是如何实现对该函数的调用的?您能够设置断点、日志记录或消息框吗?您是否尝试过另一种解决方案,也许是该问题中的“公认答案”@rsapru:您能告诉我如何使用bool进行检查吗?@p.campbell嗨,我试着修改我的问题:我现在使用的是代码,而提供的解决方案是我现在使用的。。。thanks@rsapru:boolean如果复制的最后一个数据不同,例如从其他应用程序复制时,而不是从VS复制时,则不起作用。这是您的说法。问题在于剪贴板对象中保存的许多数据格式。。现在的问题是:如何只粘贴一次剪贴板内容,因为每次哈希都不同(因为格式不同)。。。我还在一个新项目中尝试了这个类:它还粘贴了两次内容。。。你能帮我打一次粘贴信息吗??