tags:

views:

349

answers:

3

I'm doing this in C#, but, I guess, it isn't language specific problem...

I've got some sample code on how to detect when the contents of the clipboard changes. Now I want to modify the text that just got copied (strip some tags) and replace clipboard text with fixed one.

But if I SetDataObject() when I detect the clipboard contents have changed, that will generate the the message that Clipboard contents have changed again. In theory, i guess, it sounds like an infinite loop (in practice for some reason it's not).

What's the strategy to do this modification once, and sent the message down the clipboard monitoring chain?


P.S. As a test I'm doing following, but what happens is Clipboard.SetDataObject.. line gets called twice. I don't understand why, I'd expect it do this infinitely.

case Win32.Msgs.WM_DRAWCLIPBOARD:

    String clipboardText = GetClipboardText();
    if (!String.IsNullOrEmpty(clipboardText))
    {
        Clipboard.SetDataObject("test( " + clipboardText + " )!");
    }

    Win32.User32.SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);
+1  A: 

To prevent the recursion, you should only actually set the clipboard text if there were tags to strip.

To explain the behavior, I would guess that WM_DRAWCLIPBOARD isn't sent recursively, meaning that if the clipboard is changed during a WM_DRAWCLIPBOARD notification, it won't be sent again.

SLaks
+1  A: 

Unfortunately, any time you set the Clipboard's data with Clipboard.SetDataObject, you'll "redraw" the clipboard, since you're changing its contents.

The best way to handle this situation is to make your routine check the clipboard contents, and only set it if you actually change the clipboard text.

In your case, you say you're stripping out some tags. Just check the clipboardText string before and after your routine, and if the string is unchanged, don't set it again.

This way, the first time, it'll strip the tags out, then reset. Then fire again, see there are no changes, and not reset the clipboard data.

Reed Copsey
He is expecting an inifinite loop, but only seeing it happen twice in this example...
ck
But that wasn't the question. The actual question was how to handle this properly. The avoidance of the infitite loop is probably due to not passing the windows message along (trapping it) when he handles the message proc.
Reed Copsey
@Reed - there is a better way (a general one) to prevent the recursion. See my answer bellow.
Giorgi
A: 

Actually there is a much better way to avoid infinite loop which works even in cases when you are not modifying clipboard content and consequently you cannot compare if you changed it or not.

When you detect WM_DRAWCLIPBOARD message call GetClipboardOwner which will return handle to the window which modified the handle. Once you have the handle you can get the process which owns the window. If the process is different from your process then process the clipboard, otherwise the clipboard was changed by you so ignore it.

Giorgi