如何安全正确地创建Windows剪贴板的备份? [英] How do I safely and correctly create a backup of the Windows clipboard?

查看:124
本文介绍了如何安全正确地创建Windows剪贴板的备份?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建Windows剪贴板的备份。基本上,我正在使用 EnumClipboardFormats()获取当前剪贴板上存在的所有格式,然后针对每种格式,我调用 GetClipboardData(format)

I'm trying to create a backup of the Windows clipboard. Basically what I'm doing is using EnumClipboardFormats() to get all of the formats that exist on the clipboard currently, and then for each format, I'm calling GetClipboardData(format).

备份数据的一部分显然涉及复制数据。我通过调用 GlobalLock()来做到这一点(锁定全局内存对象并返回指向该对象内存块的第一个字节的指针。 )在 GetClipboardData()返回的数据上,然后我通过调用 GlobalSize()来获取数据大小,然后最后执行 memcpy()复制数据。我当然会在完成后调用 GlobalUnlock()

Part of backing up the data obviously involves duplicating it. I do that by calling GlobalLock() (which "Locks a global memory object and returns a pointer to the first byte of the object's memory block.") on the data returned by GetClipboardData(), then I fetch the size of the data by calling GlobalSize(), and then finally I do a memcpy() to duplicate the data. I then of course call GlobalUnlock() when I'm done.

嗯,这很有效...的时间。如果剪贴板包含 CF_BITMAP CF_METAFILEPICT 格式的数据,则我的程序在 GlobalLock()处崩溃。阅读此旧新事物博客帖子( http:// blogs.msdn.com/b/oldnewthing/archive/2007/10/26/5681471.aspx )我发现了崩溃的原因:显然不是剪贴板上的所有数据都是使用分配的GlobalAlloc()(例如 CF_BITMAP 数据),因此对该数据调用 GlobalLock()会导致崩溃。

Well, this works... most of the time. My program crashes at the GlobalLock() if the clipboard contains data with the format CF_BITMAP or CF_METAFILEPICT. After reading this Old New Thing blog post (http://blogs.msdn.com/b/oldnewthing/archive/2007/10/26/5681471.aspx) I found out why the crash occurs: apparently not all data on the clipboard is allocated using GlobalAlloc() (such as CF_BITMAP data), and so calling GlobalLock() on that data causes a crash.

我遇到了此MSDN文章( http://msdn.microsoft.com/zh-cn/library/ms649014#_win32_Memory_and_the_Clipboard ),它提供了剪贴板格式的列表以及它们如何被系统释放。因此,我要做的是将 GlobalFree()函数无法释放的所有剪贴板格式( CF _ * )硬编码到程序中通过系统,我只是不备份那些格式;我跳过了它们。

I came across this MSDN article ( http://msdn.microsoft.com/en-us/library/ms649014#_win32_Memory_and_the_Clipboard ) and it gives a list of clipboard formats and how they are freed by the system. So what I did was hard-code into my program all of the clipboard formats (CF_*) that are not freed by the GlobalFree() function by the system, and I simply don't back up those formats; I skip them.

实际上,这种解决方法似乎效果很好。即使剪贴板上有位图或特殊数据(例如从Excel复制到剪贴板的行),我的剪贴板备份功能也能正常工作,并且没有发生任何崩溃。另外,即使剪贴板上有位图,并且在备份过程中我跳过了某些格式(例如 CF_BITMAP ),在还原剪贴板备份后,我仍然可以Ctrl + V粘贴剪贴板中原来复制的位图,因为位图也由剪贴板上的其他格式表示,这些格式也不会导致我的程序崩溃( CF_DIB )。

This workaround seems to work well, actually. Even if a bitmap is on the clipboard, or "special" data (such as rows copied from Excel to the clipboard), my clipboard backup function works well and I haven't experienced any crashes. Also, even if there's a bitmap on the clipboard and I skip some formats during the backup (like CF_BITMAP), I can still Ctrl+V paste the originally-copied bitmap from the clipboard after restoring my clipboard backup, as the bitmap is represented by other formats on the clipboard as well that don't cause my program to crash (CF_DIB).

但是,这只是一个解决方法。我担心的是,其中一种格式有些奇怪(也许是私有格式,即 CF_PRIVATEFIRST CF_PRIVATELAST 之间的格式,或者可能是其他类型的格式)会出现在剪贴板上,我的程序在调用 GlobalLock()之后,将再次崩溃。但是,由于似乎没有太多文档说明备份剪贴板的最佳方法,因此很明显 GlobalLock()不会 对于所有数据类型都能正常工作(不幸的是),我不确定如何处理这些情况。是否可以安全地假设所有其他格式(除了先前URL中列出的 GlobalFree()不能释放的格式)都可以使用 GlobalLock()

However, it's a workaround at best. My fear is that one of these times some weird format (perhaps a private one, i.e one between CF_PRIVATEFIRST and CF_PRIVATELAST, or maybe some other type) will be on the clipboard and my program, after calling GlobalLock(), will crash again. But since there doesn't seem to be much documentation explaining the best way to back up the clipboard, and it's clear that GlobalLock() does not work properly for all datatypes (unfortunately), I'm not sure how to handle these situations. Is it safe to assume that all other formats -- besides the formats listed in the previous URL that aren't freed by GlobalFree() -- can be "grabbed" using GlobalLock()?

有任何想法吗?

推荐答案

这很愚蠢,因为您不能100%备份/还原剪贴板。许多应用使用延迟渲染,并且数据实际上不在剪贴板上。当您请求粘贴时,他们会收到通知并产生数据。要从Excel等应用程序中获取大量数据,将需要几分钟和数百MB的空间。从Excel复制时,请查看剪贴板上列出的格式数。将有两打以上,包括位图,图元文件,HTML。如果您在Excel中选择255x25000单元格并将其复制,您会怎么办?该位图有多大?提示:尝试执行此操作之前,请保存所有打开的文档,因为您可能需要重新启动。

This is folly, as you cannot 100% backup/restore the clipboard. Lots of apps used delayed rendering, and the data is not actually on the clipboard. When you request to paste, they get notified and produce the data. This would take several minutes and hundreds of MB for large amounts of data from apps like Excel. Take a look at the number of formats listed on the clipboard when you copy from Excel. There will be more than two dozen, including Bitmap, Metafile, HTML. What do you think will happen if you select 255x25000 cells in Excel and copy that? How large would that bitmap be? Tip: save any open documents before attempting this, as you're likely going to have to reboot.

这篇关于如何安全正确地创建Windows剪贴板的备份?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆