1

I am using the code in this thread to catch the Clipboard changes.

what iam exactly or what the code is exactly doing is, registering a clipboardviewer for my application to be able to catch all the clipboard changes made.

once the clipboard changes the WndProc will fire and run the OnClipboardChanged() function..

iam copying the text from visual studio as example by using the keyboard shortcut (Ctrl+C)

When I copy from Visual Studi,, the data will be pasted twice, which means the WM_DRAWCLIPBOARD is called twice?(please check the code)

How can i check or stop this behaviour?

I just want to make sure that the data pasted won't be duplicated.?

Community
  • 1
  • 1
  • Not sure why is it being called twice but you can always use a boolean to check. – rsapru Feb 12 '11 at 16:22
  • edit your question to include the exact steps you take when copying text from an application. How did you implement the call to this function? Are you able to set breakpoints, logging, or msg boxes? Did you try another solution, perhaps the 'accepted answer' in that question? – p.campbell Feb 12 '11 at 16:22
  • @rsapru: can you please tell me how to use the bool to check ? – csharpclipboard Feb 12 '11 at 16:42
  • @ p.campbell hi, i tried to modify my question: iam using the code as it is...and the solution provided there is that what iam using right now ...thanks – csharpclipboard Feb 12 '11 at 16:43
  • @rsapru: boolean won't work if the last data being copied is different, like when copying from other app than VS. – Nicolas Buduroi Feb 12 '11 at 16:48
  • @csharpclipboard: as p.campbell said there's probably something you're doing wrong. By the way your question could use some formatting! – Nicolas Buduroi Feb 12 '11 at 16:50

2 Answers2

0

I know that this is an known error somewhere in the ClipboardChain. What you can simply do against this behavior is filter those pseudo calls. I am just checking if the timespan between the calls seems to be human. here it goes:

    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);
        }
    }
Jens Marchewka
  • 1,372
  • 1
  • 13
  • 22
0

You could store the hash code of the data being copied and look if the last one match. Here's an untested example for text data objects:

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

I'm not sure of the best way to do it in generically, you could always use GetFormats() and retrieve all format+hash pairs and do the lookup with them as I'm not sure there can't be clashes across different formats.

Nicolas Buduroi
  • 3,565
  • 1
  • 28
  • 29
  • its true what ur saying..the problem is with the many Dataformats saved in the clipboard object.. The problem now is : How can i only paste the clipboard contents once cause the Hash is different everytime (because of the different formats)... i also tried this class here in a new project: http://dotnet-snippets.de/dns/multiclipboard-oder-besser-clipboardchangedevent-SID674.aspx it is also pasting the contents twice... could you please help me to call the Paste message only once?? – csharpclipboard Feb 12 '11 at 23:34