如何保存剪贴板的副本然后还原到它?

我正在通过模拟高亮和复制文本所需的按键来在文本框中阅读单词。 当我完成后,我希望剪贴板正是我找到它的方式。

我希望我能做到这样的事情:

IDataObject clipboardBackup = Clipboard.GetDataObject(); Clipboard.Clear(); //Save other things into the clipboard here, etc// Clipboard.SetDataObject(clipboardBackup); 

但这似乎不起作用。 看起来你可以走专门尝试文本,音频,图片等的路线,然后相应地保存它们。 (我猜’数据对象’在我的例子中也是专门的,我希望它是通用的。)

我不希望对每种可能类型的剪贴板数据都使用案例,既要更简洁,又要确保不管格式如何都不会丢失数据。

抓住任何和所有剪贴板然后恢复它的任何提示?

除非登录用户直接指示,否则请勿使用剪贴板。 它不适用于一般应用程序存储 – 用户可以使用它们进行剪辑。

如果要从任意文本框中获取文本,请找到窗口(在Win32中)并发送EM_GETTEXT Win32消息。

以下文章介绍了备份和还原剪贴板的一些代码。 它可能比人们想象的更多,所以我不会在这里重新发布代码。

C#中的剪贴板备份

在使用延迟渲染的情况下,或者剪贴板数据实际上包含指向本地程序的指针而不是其他程序使用它们时,不可能完全恢复剪贴板(哑巴,但我已经看过了)。 考虑Excel的经典示例,使用延迟渲染以几十种不同的格式提供相同的选择,包括Bitmap和HTML等危险的格式(如果复制了数千个单元格,可能会消耗数百MB和几分钟的时间进行渲染) 。 然后,其他剪贴板查看器的整个情况会对剪贴板操作做出反应。 他们将获得重复数据,更改数据或剪贴板已被删除的通知。
我认为这总结得最好:

“如果没有用户的明确指示,程序不应将数据传输到我们的剪贴板中。”
– Charles Petzold,Windows 3.1编程,微软出版社,1992年

我用c ++实现了一个样本。

 #include "stdafx.h" #include "TestClip.h" #include  #include  using namespace std; typedef struct { UINT format; LPVOID content; SIZE_T size; } ClipBoardItem; void InspectClipboard() { UINT uFormat = 0; HGLOBAL hglb; LPVOID hMem; float totalSize = 0; if (!OpenClipboard(NULL)) { cout << "Open clipboard failed!" << endl; system("pause"); return; } int countFormat = CountClipboardFormats(); cout << "Clipboard formats count: " << countFormat << endl; uFormat = EnumClipboardFormats(uFormat); while (uFormat) { cout << "Clipboard format:" << uFormat; hglb = GetClipboardData(uFormat); if (hglb != NULL) { hMem = GlobalLock(hglb); SIZE_T size = GlobalSize(hMem); cout << ", size:" << size << endl; totalSize += size; if (hMem != NULL) { GlobalUnlock(hglb); } } else { cout << " data is NULL" << endl; } uFormat = EnumClipboardFormats(uFormat); } CloseClipboard(); string unit = "bytes"; if (totalSize >= 1024) { totalSize /= 1024; unit = "KB"; } if (totalSize >= 1024) { totalSize /= 1024; unit = "MB"; } if (totalSize >= 1024) { totalSize /= 1024; unit = "GB"; } cout << "Total size is: " << totalSize << " " << unit.data() << endl; } queue BackupClipboard() { queue clipQueue; UINT uFormat = 0; HGLOBAL hglb; LPTSTR lptstr; LPVOID hMem; if (!OpenClipboard(NULL)) { cout << "Open clipboard failed" << endl; return clipQueue; } uFormat = EnumClipboardFormats(uFormat); while (uFormat) { cout << "Backup clipboard format:" << uFormat << endl; hglb = GetClipboardData(uFormat); if (hglb != NULL) { hMem = GlobalLock(hglb); SIZE_T size = GlobalSize(hMem); if (size > 0) { ClipBoardItem clipitem; clipitem.format = uFormat; clipitem.content = malloc(size); clipitem.size = size; memcpy(clipitem.content, hMem, size); clipQueue.push(clipitem); } if (hMem != NULL) { GlobalUnlock(hglb); } } uFormat = EnumClipboardFormats(uFormat); } EmptyClipboard(); CloseClipboard(); cout << "Clipboard has been cleaned" << endl; return clipQueue; } void RestoreClipboard(queue clipQueue) { if (!OpenClipboard(NULL)) return; while (!clipQueue.empty()) { ClipBoardItem clipitem = clipQueue.front(); HGLOBAL hResult = GlobalAlloc(GMEM_MOVEABLE, clipitem.size); if (hResult == NULL) { cout << "GlobalAlloc failed" << endl; clipQueue.pop(); continue; } memcpy(GlobalLock(hResult), clipitem.content, clipitem.size); GlobalUnlock(hResult); if (SetClipboardData(clipitem.format, hResult) == NULL) { cout << "Set clipboard data failed" << endl; } cout << "Resotred clipboard format:" << clipitem.format << endl; GlobalFree(hResult); free(clipitem.content); clipQueue.pop(); } CloseClipboard(); } int _tmain(int argc, TCHAR* argv [], TCHAR* envp []) { InspectClipboard(); cout << "Press any key to backup and empty clipboard" << endl; system("pause"); queue clipQueue = BackupClipboard(); InspectClipboard(); cout << "Press any key to restore clipboard" << endl; system("pause"); RestoreClipboard(clipQueue); cout << "Clipboard has been restored" << endl; system("pause"); InspectClipboard(); system("pause"); return 0; } 

希望这可以帮助!

如果我在你的位置,我会考虑恢复剪贴板的要求。 通常情况下,剪贴板上的数据量将相对较小(一个文本块,一个来自网站的图像,类似的东西),但是偶尔你会遇到用户的情况。可能在一段时间之前已经在剪贴板上放置了大量数据,并且可能不再需要。 您的应用必须足够强大,以便在您的操作生命周期内临时存储所有数据。 虽然你比我更了解情况,但我个人并不认为这是值得的。

总之,不要。 只需使用Clipboard.Clear();清除剪贴板Clipboard.Clear(); 你做完之后