Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何保存剪贴板的副本,然后恢复到剪贴板?_C#_Clipboard - Fatal编程技术网

C# 如何保存剪贴板的副本,然后恢复到剪贴板?

C# 如何保存剪贴板的副本,然后恢复到剪贴板?,c#,clipboard,C#,Clipboard,我在一个文本框中通过模拟高亮度和复制文本所需的按键来阅读单词。当我完成后,我希望剪贴板就是我找到它的方式 我希望我能做这样的事情: IDataObject clipboardBackup = Clipboard.GetDataObject(); Clipboard.Clear(); //Save other things into the clipboard here, etc// Clipboard.SetDataObject(clipboardBackup); 但这似乎不起作用。看起来,您

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

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

IDataObject clipboardBackup = Clipboard.GetDataObject();
Clipboard.Clear();
//Save other things into the clipboard here, etc//
Clipboard.SetDataObject(clipboardBackup);
但这似乎不起作用。看起来,您可以专门尝试文本、音频、图片等,然后相应地保存它们。(我猜“数据对象”也像我的示例中那样专门化,我希望它是通用的。)

我不希望对每一种可能的剪贴板数据类型都使用用例,这不仅是为了更简洁,而且是为了确保无论格式如何,我都不会丢失数据


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

< P>我会考虑恢复剪贴板的要求,如果我处在你的位置。通常情况下,剪贴板上的数据量相对较小(一块文本、来自网站的图像,诸如此类),但偶尔您会遇到这样的情况:用户可能在一段时间前将大量数据放在剪贴板上,并且可能不再需要。你的应用程序必须足够健壮,能够在你的操作生命周期内临时存储所有这些数据。我个人认为这不值得付出努力,尽管你比我更了解情况


简言之,不要这样做。只需使用
clipboard.clear()清除剪贴板即可完成后。

除非登录用户直接指示,否则不要使用剪贴板。它不是用于一般的应用程序存储,而是供用户用于他们想要剪辑的内容


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

以下文章介绍了一些备份和还原剪贴板的代码。它的内容超出了人们的想象,因此我不会在这里重新发布代码


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

“在没有用户明确指示的情况下,程序不应将数据传输到我们的剪贴板中。”

- Charles Petzold,编程Windows 3.1,微软出版社,1992 < /P> < P>我用C++实现了一个示例。p>
#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;
}
#包括“stdafx.h”
#包括“TestClip.h”
#包括
#包括
使用名称空间std;
类型定义结构
{
UINT格式;
LPVOID含量;
大小;
}剪贴簿;
作废剪贴板()
{
UINT uFormat=0;
HGLOBAL-hglb;
LPVOID-hMem;
float totalSize=0;
如果(!OpenClipboard(NULL))
{

可能这里的问题根本就在于使用剪贴板。你能不能再多说一点你为什么选择这条路线,以及你想达到什么目的?从文本框中阅读单词似乎根本不需要使用剪贴板…它从任何文本框中读取文本。不只是从我的应用程序或其他任何程序中读取文本,所以(我不这么认为)我可以访问我想要文本的文本框。如果我错了,我希望不能做这个复制/粘贴的事情。这不是我的否决票,但这样做会让用户讨厌这个应用程序。剪贴板和上面的数据属于用户,而不是任何想使用它的任意应用程序。是的,我原则上同意,但这整个u唱剪贴板是一个非常棘手的领域-我知道,因为我过去不得不这么做。最后,牺牲剪贴板上的一条数据在我的情况下被认为是值得的。这就是为什么我主张OP在撕掉他/她的头发之前做进一步的分析,以确保需求确实存在。