如何保存剪贴板的副本,然后还原为它?
我正在阅读文本框中的文字,通过模拟高亮度所需的按键并复制文本。当我完成后,我希望剪贴板完全符合我的发现。如何保存剪贴板的副本,然后还原为它?
我希望我能够做这样的事情:
IDataObject clipboardBackup = Clipboard.GetDataObject();
Clipboard.Clear();
//Save other things into the clipboard here, etc//
Clipboard.SetDataObject(clipboardBackup);
但是,这似乎并没有工作。它看起来像你可以走专门尝试文字,音频,图片等路线,然后相应地保存它们。 (我猜'数据对象'在我的例子中也是这样的,我希望它是通用的。)
我不希望为每种可能的剪贴板数据类型使用例子,以确保我不会丢失数据而不管格式。
任何提示抓取任何和所有的剪贴板,然后恢复它?
除非直接由登录用户指示,否则请勿使用剪贴板。它不适用于一般的应用程序存储 - 它是供用户使用它们想要剪辑的内容。
如果您想从任意文本框中获取文本,请找到该窗口(在Win32中)并发送一个EM_GETTEXT
Win32消息。
如果我处于您的位置,我会考虑恢复剪贴板的要求。通常情况下,剪贴板上的数据量将会相对较小(文本块,网站图像等),但您偶尔会遇到这样一种情况,即用户已经在剪贴板上放置了大量的数据,可能前一段时间,并且可能不再需要。您的应用程序必须足够强大,才能应对在您的操作生命周期中临时存储所有数据。我个人认为这不太可能是值得的,尽管你比我知道的情况要好得多。
总之,不要。完成后请清除剪贴板Clipboard.Clear();
。
不是我的失望,但这样做*会让用户讨厌应用程序。剪贴板和它上面的数据属于用户,而不是任何使用它的任意应用程序。 – AakashM 2010-02-11 09:17:51
是的,我原则上同意,但是使用剪贴板这一整个领域是一个非常棘手的领域 - 我知道,因为我必须在过去这样做。最后,在我的情况下,牺牲剪贴板上的单个数据被认为是值得的。这就是为什么我主张OP进行进一步的分析,以确保在将自己的头发撕掉之前确实存在需求。 – ZombieSheep 2010-02-11 09:22:09
这是不可能完全恢复,在使用延迟渲染的情况下,剪贴板,或在剪贴板中的数据实际上包含指针回不打算供其他程序使用这些本地程序(哑,但我见过它)。考虑一下Excel的典型例子,它使用延迟渲染来提供数十种不同格式的相同选择,包括Bitmap和HTML等危险内容(如果复制数千个单元格,则可能会消耗数百MB和几分钟的时间进行渲染) 。 然后就是其他剪贴板查看器对剪贴板操作作出反应的整个情况。他们会得到重复的数据,更改的数据或通知剪贴板已被删除。
我觉得这个总结得非常好:
- 查尔斯Petzold的,编程Windows 3“程序不应数据,而无需来自用户的明确指令转移到我们的出剪贴板的。”1,Microsoft Press,1992
我已经用C++实现了一个示例。
#include "stdafx.h"
#include "TestClip.h"
#include <Windows.h>
#include <queue>
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<ClipBoardItem> BackupClipboard()
{
queue<ClipBoardItem> 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<ClipBoardItem> 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<ClipBoardItem> 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;
}
希望这有助于!
也许这里的问题是使用剪贴板。你能否更多地解释为什么你选择了这条路线以及你想要达到的目标?从文本框中读取单词似乎不是一个应该需要使用剪贴板的任务... – ZombieSheep 2010-02-11 08:55:18
它从* ANY *文本框中读取文本。不只是从我的应用程序或其他什么,所以(我不认为)我有权访问我想要的文本框。如果我错了,我很乐意不能做这个复制/粘贴的东西。 – cksubs 2010-02-11 08:59:46