我会尽力详细解释我想要实现的目标。
我正在使用带有IntPtr窗口句柄的C#来从我自己的C#应用程序对外部应用程序执行CTRL-C复制操作。我不得不这样做,因为无法使用GET_TEXT直接访问文本。然后我在我的应用程序中使用该副本的文本内容。这里的问题是我现在已经覆盖了剪贴板。
我希望能做的是:
这是我到目前为止尝试过的代码:
private void GetClipboardText()
{
text = "";
IDataObject backupClipboad = Clipboard.GetDataObject();
KeyboardInput input = new KeyboardInput(this);
input.Copy(dialogHandle); // Performs a CTRL-C (copy) operation
IDataObject clipboard = Clipboard.GetDataObject();
if (clipboard.GetDataPresent(DataFormats.Text))
{
// Retrieves the text from the clipboard
text = clipboard.GetData(DataFormats.Text) as string;
}
if (backupClipboad != null)
{
Clipboard.SetDataObject(backupClipboad, true); // throws exception
}
}
我使用的是System.Windows.Clipboard而不是System.Windows.Forms.Clipboard。原因是当我执行CTRL-C时,System.Windows.Forms中的Clipboard类没有返回任何数据,但系统剪贴板却没有。
我研究了一些低级别的user32调用,比如OpenClipboard,EmptyClipboard和CloseClipboard,希望它们可以帮助我做到这一点,但到目前为止,我一直在尝试恢复时遇到COM异常。
我想也许这与OpenClipboard参数有关,该参数期望一个想要控制剪贴板的应用程序的IntPtr窗口句柄。由于我提到我的应用程序没有GUI,这是一个挑战。我不知道该在这里传递什么。也许有人可以对此有所了解?
我是否错误地使用了Clipboard类?有没有明确的方法来获取没有GUI的应用程序的IntPtr窗口句柄?有谁知道备份和恢复系统剪贴板的更好方法?
答案 0 :(得分:19)
尝试这样做是愚蠢的。您无法忠实地将剪贴板恢复到先前的状态。使用“延迟呈现”可能存在数十种未呈现的数据格式,如果您尝试全部呈现它们,则会导致源应用程序耗尽资源。这就像走进餐厅并说“给我一切”。
假设用户在Excel中选择了500行x 100列,并将其复制到剪贴板。 Excel“宣传”它可以以大约25种不同的格式生成这些数据,包括Bitmap。将其粘贴为位图后,可以强制Excel将其渲染为位图。这是50000个单元格,大约是10,000 x 15,000像素的位图。而且你希望用户在Excel咳嗽时等待,以及其他24种格式?不可行。
此外,您将触发WM_DrawClipboard事件,这将影响其他剪贴板查看器。
放弃。
答案 1 :(得分:6)
您可以将剪贴板的内容保存在字典中,然后将其恢复:
public IDictionary<string, object> GetClipboardData()
{
var dict = new Dictionary<string, object>();
var dataObject = Clipboard.GetDataObject();
foreach(var format in dataObject.GetFormats())
{
dict.Add(format, dataObject.GetData(format));
}
return dict;
}
public void SetClipboardData(IDictionary<string, object> dict)
{
var dataObject = Clipboard.GetDataObject();
foreach(var kvp in dict)
{
dataObject.SetData(kvp.Key, kvp.Value);
}
}
...
var backup = GetClipboardData();
// Do something with the clipboard...
...
SetClipboardData(backup);