How to save a copy of the clipboard and then return to it?

I read the words in the text box, simulating the keystrokes required to enlarge and copy text. When I'm done, I want the clipboard to be exactly the way I found it.

I was hoping I could do something like this:

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

But that does not work. It looks like you can go the route specifically for text, sound, images, etc., and then save them accordingly. (I think the “data object” is also specialized in my example, I was hoping it would be common.)

I would prefer not to use cases for all possible data types in the clipboard, so that they are more concise and that I never lose data regardless of format.

Any tips on capturing any and all clipboard and then restoring it?

+4
source share
5 answers

Do not use the clipboard unless indicated directly by the logged in user. This is not for general application storage - it is for the user to use for what they want the clip.

If you want to get text from an arbitrary text field, find the window (in Win32) and send the message EM_GETTEXT Win32.

+3
source

The following article provides code for backing up and restoring the clipboard. There is more than you could imagine, so I will not rewrite the code here.

Clipboard backup in C #

+2
source

It is not possible to completely restore the clipboard in cases where deferred rendering is used, or when the clipboard data actually contains pointers back to the local program that are not intended for use by other programs (dumb, but I saw It). Let's look at a classic Excel example, using deferred rendering, to offer the same choice in dozens of different formats, including such dangerous ones as Bitmap and HTML (it can consume hundreds of MB and several minutes of time to render if thousands of cells are copied), and then comes up A situation where other clipboard viewers react to your manipulations with the clipboard. They will receive duplicate data, changed data, or a notification that the clipboard has been deleted.
I think this sums it up:

"Programs should not transfer data to ours from the clipboard without explicit instructions from the user."
- Charles Petzold, Windows 3.1 Programming, Microsoft Press, 1992

+2
source

I am implementing one example with 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; } 

Hope this helps!

0
source

I would consider the requirement to restore the clipboard in general if I were in your place. Most often, the amount of data in the clipboard will be relatively small (a block of text, an image from the site, something like that), but from time to time you encounter a situation where the user has posted a large amount of data in the clipboard, perhaps some time ago and may no longer be required. Your application must be reliable enough to handle the temporary storage of all this data for the duration of your operation. I personally do not think that this may be worth the effort, although you know the situation better than I could.

In short, no need. Just clear the clipboard with Clipboard.Clear(); after you are done.

-1
source

Source: https://habr.com/ru/post/1300965/


All Articles