我正在尝试创建Windows剪贴板的备份.基本上我正在做的是使用EnumClipboardFormats()
当前剪贴板上存在的所有格式,然后对于每种格式,我正在调用GetClipboardData(format)
.
备份数据的一部分显然涉及重复数据.我这样做是通过调用GlobalLock()
("锁定一个全局内存对象并返回指向对象内存块的第一个字节的指针.")对返回的数据GetClipboardData()
,然后通过调用获取数据的大小GlobalSize()
,然后最后我做一个memcpy()
复制数据.当然,GlobalUnlock()
当我完成时,我当然会打电话.
嗯,这很有用......大多数时候.GlobalLock()
如果剪贴板包含格式为CF_BITMAP或CF_METAFILEPICT的数据,则我的程序崩溃.在阅读了这篇Old New Thing博客文章(http://blogs.msdn.com/b/oldnewthing/archive/2007/10/26/5681471.aspx)后,我发现了崩溃发生的原因:显然不是剪贴板上的所有数据使用GlobalAlloc()
(例如CF_BITMAP数据)分配,因此调用GlobalLock()
该数据会导致崩溃.
我遇到了这篇MSDN文章(http://msdn.microsoft.com/en-us/library/ms649014#_win32_Memory_and_the_Clipboard),它给出了一个剪贴板格式列表以及它们如何被系统释放.所以我所做的是将所有剪贴板格式(CF_*)硬编码到我的程序中,这些格式化系统没有被GlobalFree()
函数释放,我只是不备份这些格式; 我跳过它们.
实际上,这种解决方法似乎运作良好.即使位图放在剪贴板上,或"特殊"数据(例如从Excel复制到剪贴板的行),我的剪贴板备份功能也能正常运行,而且我没有遇到任何崩溃.此外,即使剪贴板上有位图并且我在备份期间跳过一些格式(如CF_BITMAP),我仍然可以在恢复剪贴板备份后按Ctrl + V从剪贴板粘贴原始复制的位图,因为位图由剪贴板上的其他格式也不会导致我的程序崩溃(CF_DIB).
但是,这是最好的解决方法.我担心的是,其中一种奇怪的格式(可能是私有格式,即CF_PRIVATEFIRST和CF_PRIVATELAST之间的格式,或者可能是其他类型)将在剪贴板上,我的程序在调用GlobalLock()
之后将再次崩溃.但是因为似乎没有太多文档解释备份剪贴板的最佳方法,并且很明显,对于所有数据类型GlobalLock()
都不能正常工作(不幸的是),我不知道如何处理这些情况.是否可以安全地假设所有其他格式 - 除了上一个URL中列出的未被释放的格式GlobalFree()
- 可以被"抓取"使用GlobalLock()
?
有任何想法吗?
这是愚蠢的,因为您无法 100% 备份/恢复剪贴板。许多应用程序使用延迟渲染,并且数据实际上并不在剪贴板上。当您请求粘贴时,他们会收到通知并生成数据。对于来自 Excel 等应用程序的大量数据,这将需要几分钟和数百 MB 的时间。从 Excel 复制时,查看剪贴板上列出的格式数量。会有两打以上,包括Bitmap、Metafile、HTML。如果您在 Excel 中选择 255x25000 单元格并复制它,您认为会发生什么?该位图有多大?提示:在尝试此操作之前,请保存所有打开的文档,因为您可能需要重新启动。
归档时间: |
|
查看次数: |
791 次 |
最近记录: |