【发布时间】:2012-08-23 03:54:15
【问题描述】:
我正在开发一个剪贴板管理器(可以在这里看到:http://flamefusion.net/software/shapeshifter)。
但是,我目前遇到的问题是位图 (bmp) 无法真正正确地插入剪贴板。我的第一种方法如下,使用SetClipboardData。
var hBitmap = bmp.GetHBitmap();
SetClipboardData(CF_BITMAP, hBitmap);
我知道其中存在潜在的内存泄漏,这只是作为测试。测试失败。粘贴到剪贴板中的图像在粘贴时无法被 Paint 读取。
所以经过大量的研究和失败的尝试,我得到了一个新的理论。我使用的位图是从MemoryStream 创建的,它是通过先前调用Bitmap.Save(Stream, ImageFormat) 方法创建的。这让我相信System.Drawing.Bitmap 的GetHBitmap 不是SetClipboardData 函数所期望的那种HBITMAP。
所以我尝试了以下方法,取得了某种成功。
var memDC = CreateCompatibleDC(IntPtr.Zero);
var memBitmap = CreateCompatibleBitmap(memDC, bmp.Width, bmp.Height);
SetClipboardData(CF_BITMAP, memBitmap);
现在图像以正确的尺寸插入,但作为黑色图像。这很明显,因为bmp 中的任何内容实际上都没有用于创建“兼容”位图,除了其宽度和高度。
我假设我必须以某种方式使用 BitBlt 将我的原始位图复制到这个现在“兼容”的位图,但我不知道从哪里开始。
你们中的任何一个 GDI 向导都知道吗?这里显然需要魔法。
编辑 1 正如 dthorpe 很好地指出的那样,我的问题似乎是我试图保存的图像实际上是一个 DIB。现在问题变了。我需要弄清楚如何从 DIB 转换为 DDB。我知道在执行此操作时会导致 alpha 损失,但仍然需要它。
编辑 2
使用Clipboard.SetImage 是不可接受的。这在我的场景中不起作用。我需要使用 API。
【问题讨论】:
-
GetHBitmap() 应该可以在剪贴板中正常工作。您确定原始位图有效吗?你能在屏幕上显示原始位图(从内存流创建)吗?
-
您不想转换为 DDB。你想
Bitmap.Save(Stream, ImageFormat.Bmp),然后用CF_DIB把它放到剪贴板中。 -
无法在 Paint 中显示。你能用实际证明它有效的代码来回答吗?
标签: c# pinvoke gdi+ clipboard gdi