如何安全、正确地创建 Windows 剪贴板的备份?

2024-04-04

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

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

嗯,这在大多数情况下都有效。我的程序崩溃于GlobalLock()如果剪贴板包含以下格式的数据CF_位图 or CF_元文件图片。阅读这篇旧新事物博客文章后(https://devblogs.microsoft.com/oldnewthing/20071026-00/?p=24683 https://devblogs.microsoft.com/oldnewthing/20071026-00/?p=24683)我发现了崩溃发生的原因:显然并非剪贴板上的所有数据都是使用分配的GlobalAlloc()(例如CF_位图数据),所以调用GlobalLock()该数据会导致崩溃。

我碰到这篇 MSDN 文章 https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard-operations它给出了剪贴板格式的列表以及系统如何释放它们。所以我所做的是将所有剪贴板格式硬编码到我的程序中(CF_*)未被释放的GlobalFree()系统功能,我根本不备份这些格式;我跳过它们。

事实上,这个解决方法看起来效果很好。即使剪贴板上有位图或“特殊”数据(例如从 Excel 复制到剪贴板的行),我的剪贴板备份功能也运行良好,并且没有遇到任何崩溃。另外,即使剪贴板上有位图并且我在备份期间跳过某些格式(例如CF_位图),在恢复剪贴板备份后,我仍然可以 Ctrl+V 从剪贴板粘贴最初复制的位图,因为位图也以剪贴板上的其他格式表示,这不会导致我的程序崩溃(CF_DIB).

然而,这充其量只是一种解决方法。我担心的是,其中一次会出现某种奇怪的格式(可能是私人格式,即介于CF_PRIVATEFIRST and CF_PRIVATELAST,或者可能是其他类型)将在剪贴板和我的程序上,调用后GlobalLock(),又会崩溃。但由于似乎没有太多文档解释备份剪贴板的最佳方法,而且很明显GlobalLock() does not对于所有数据类型都可以正常工作(不幸的是),我不确定如何处理这些情况。是否可以安全地假设所有其他格式(除了前面 URL 中列出的未由GlobalFree()-- 可以使用“抓取”GlobalLock()?

有任何想法吗?


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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何安全、正确地创建 Windows 剪贴板的备份? 的相关文章

随机推荐