从 http://msdn.microsoft.com/en-us/library/k061we7x%28VS.80%29.aspx 的
然而,通过 Reflector 查看
GDI+ 扁平 API 函数的文档相当少,但是 http://msdn.microsoft.com/en-us/library/ms533971%28VS.85%29.aspx 表示,
此版本的
我看不出
此外,GDI+文档警告不要使用当前或先前选择到设备上下文中的源HBITMAP。虽然我可以理解为什么位图不应当前选择到设备上下文中,但我不明白为什么有警告不要使用之前选择到设备上下文中的位图。这似乎会防止使用使用标准GDI在内存中创建的GDI+位图。
因此,总结如下:
Image.FromHbitmap()
文档中可以看到:
这明确说明,位图句柄可以在 Bitmap 实例创建后立即使用 DeleteObject 删除。FromHbitmap 方法复制了 GDI 位图;所以您可以在创建新的 Image 后立即使用 GDIDeleteObject 方法释放传入的 GDI 位图。
然而,通过 Reflector 查看
Image.FromHbitmap()
的实现可以发现它是一个非常薄的包装器,包装了 GDI+ 函数 GdipCreateBitmapFromHBITMAP()
。GDI+ 扁平 API 函数的文档相当少,但是 http://msdn.microsoft.com/en-us/library/ms533971%28VS.85%29.aspx 表示,
GdipCreateBitmapFromHBITMAP()
对应于 Bitmap::Bitmap()
构造函数,该构造函数接受 HBITMAP
和 HPALETTE
作为参数。此版本的
Bitmap::Bitmap()
构造函数的文档在 http://msdn.microsoft.com/en-us/library/ms536314%28VS.85%29.aspx 中有这样的说明:
此外,可以在 GdiPlusBitmap.h 的 C++ 部分的源代码中看到,该构造函数本身是您负责删除 GDI 位图和 GDI 调色板。但是,在删除或超出范围之前,不应删除 GDI 位图或 GDI 调色板。
不要将当前(或先前)选择到设备上下文中的 GDI 位图或 GDI 调色板传递给 GDI+ Bitmap::Bitmap 构造函数。
GdipCreateBitmapFromHBITMAP()
扁平 API 函数的包装器。inline
Bitmap::Bitmap(
IN HBITMAP hbm,
IN HPALETTE hpal
)
{
GpBitmap *bitmap = NULL;
lastResult = DllExports::GdipCreateBitmapFromHBITMAP(hbm, hpal, &bitmap);
SetNativeImage(bitmap);
}
我看不出
GdipCreateBitmapFromHBITMAP()
的实现方式,这是该功能的核心,但文档中的两个备注似乎相互矛盾。.Net文档说我可以立即删除位图句柄,而GDI+文档则表示必须保留位图句柄,直到包装对象被删除,但两者都基于同一GDI+函数。此外,GDI+文档警告不要使用当前或先前选择到设备上下文中的源HBITMAP。虽然我可以理解为什么位图不应当前选择到设备上下文中,但我不明白为什么有警告不要使用之前选择到设备上下文中的位图。这似乎会防止使用使用标准GDI在内存中创建的GDI+位图。
因此,总结如下:
- 原始位图句柄需要保留直到 .Net Bitmap 对象被处理吗?
- GDI+函数
GdipCreateBitmapFromHBITMAP()
是否复制源位图或只保留对原始位图的句柄? - 为什么不应使用先前选择到设备上下文中的 HBITMAP?