我正在尝试编写一个需要使用剪贴板来实现某些功能的小应用程序。由于我不想覆盖当前在剪贴板中的用户数据,我决定将其保存到内存中,完成我的工作然后将其写回。下面的代码是一个控制台应用程序,它是我正在尝试做的一个准确的例子。
我遇到的问题是恢复状态。如果我在运行应用程序之前从Visual Studio将某些内容复制到剪贴板,则剪贴板中总共有六个对象(各种字符串格式和一个区域设置)都将放入缓存中。一旦我恢复它们,虽然只有区域设置在剪贴板中,并且每次调用SetData()都会覆盖最后一个。 (顺便说一下,SetDataObject似乎不是GetDataObject的反转,所以我不能只使用它)
任何想法如何存储剪贴板状态并在以后恢复它?
[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();
}
答案 0 :(得分:5)
Windows剪贴板一次只有一个对象。但是,有一种对象可以使用多种格式(例如RTF,Text,HTML)。我认为你太复杂了,你的代码应该是这样的:
//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();
答案 1 :(得分:1)
Martin我已经尝试过你的代码了。我在我的系统上安装了ClipX。当我运行你的代码时运行它我得到的数量与ClipX的缓存一样多。但是调用Clipboard.GetDataObject()
只返回最新的对象。那么当你调用这个循环时会发生什么:
foreach (string format in clipboardData.GetFormats())
{
clipboardCache.Add(format, clipboardData.GetData(format));
}
它返回ClipX中所有对象的格式并转换
返回的数据IDataObject clipboardData = Clipboard.GetDataObject();
所以实际上当你执行这个循环时
foreach (KeyValuePair<string, object> valuePair in clipboardCache)
{
Clipboard.SetData(valuePair.Key, valuePair.Value);
Thread.Sleep(100);
}
您只有一个对象被设置为剪贴板。
其次,当使用Clipboard.SetData(format,object)
覆盖旧对象时,新对象是正常行为而不是正常行为。如果要构建多个条目剪贴板,则需要拦截复制和粘贴系统调用,并将对象保留在程序的内存或磁盘中。您不能依赖默认剪贴板。