Modifying clipboard contents on clipboard change
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);
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.
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.
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.
精彩评论