Strangeness with clipboard access

人走茶凉 提交于 2019-12-18 16:51:43

问题


I'm trying to write a small application that needs to use the clipboard for some functionality. Since I don't want to overwrite the user's data currently in the clipboard I decided to save it to memory, do my job and then write it back. The code below is a console application that is a barebones example of what I'm trying to do.

The problem I'm having is restoring the state. If I copy something to the clipboard from Visual Studio before running the application there are a total of six objects in the clipboard (various string formats and a locale) which all get put in the cache. Once I restore them though only the locale is in the clipboard and it appears each call to SetData() overwrites the last. (by the way SetDataObject doesn't seem to be the inverse of GetDataObject so I can't just use that)

Any ideas how I can store clipboard state and restore it later?

    [STAThread]
    static void Main(string[] args)
    {
        //Store the old clipboard data
        Dictionary<string, object> clipboardCache = new Dictionary<string, object>();

        IDataObject clipboardData = Clipboard.GetDataObject();

        foreach (string format in clipboardData.GetFormats())
        {
            clipboardCache.Add(format, clipboardData.GetData(format));
        }

        Clipboard.SetText("Hello world!");

        string value = Clipboard.GetText();

        Console.WriteLine(value);

        //Clear the clipboard again and restore old data
        Clipboard.Clear();

        foreach (KeyValuePair<string, object> valuePair in clipboardCache)
        {
            Clipboard.SetData(valuePair.Key, valuePair.Value);
            Thread.Sleep(100);
        }

        Console.ReadLine();
    }

回答1:


The windows clipboard only has one object in it at a time. But there are multiple formats available (e.g. RTF, Text, HTML) from that one object. I think you are making it too complicated and your code should be something like this:

//Store the old clipboard data
IDataObject clipboardData = Clipboard.GetDataObject();

Clipboard.SetText("Hello world!");

string value = Clipboard.GetText();
Console.WriteLine(value);

//Clear the clipboard again and restore old data
Clipboard.Clear();
Clipboard.SetDataObject(clipboardData);

Console.ReadLine();



回答2:


Martin I've tried your code. I have ClipX installed on my system. With it running when I run your code I get as many items as there in ClipX's cache. But the call Clipboard.GetDataObject() returns only the latest object. So what happens is that when you call this loop:

foreach (string format in clipboardData.GetFormats())
{
    clipboardCache.Add(format, clipboardData.GetData(format));
}

it returns the format for all the object in the ClipX and convert the data returned by

IDataObject clipboardData = Clipboard.GetDataObject();

So actually when you are executing this loop

foreach (KeyValuePair<string, object> valuePair in clipboardCache)
{
    Clipboard.SetData(valuePair.Key, valuePair.Value);
    Thread.Sleep(100);
}

you have only one object which is being set to clipboard.

Secondly when using Clipboard.SetData(format,object) overwriting older object with new one is normal behaviour not the normal one. If you are building multiple entry clipboard sort of thing then you need to intercept copy and paste system calls and keep the object in your program's memory or disk. You cannot rely on default clipboard.



来源:https://stackoverflow.com/questions/1374584/strangeness-with-clipboard-access

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!