從Image.FromHbitmap()
在http://msdn.microsoft.com/en-us/library/k061we7x%28VS.80%29.aspx的文檔:使用Image.FromHbitmap()構造位圖時,原始位圖句柄多久可以刪除?
的FromHbitmap方法使GDI位圖的副本;因此您可以在創建新映像後立即使用GDIDeleteObject方法釋放傳入的GDI位圖。
這非常明確地規定,只要Bitmap實例被創建,位圖句柄就可以立即用DeleteObject刪除。
然而,使用Reflector查看Image.FromHbitmap()
的實現,表明它是GDI +函數GdipCreateBitmapFromHBITMAP()
的一個很薄的包裝。
上有GDI +平坦API函數相當稀少的文檔,但http://msdn.microsoft.com/en-us/library/ms533971%28VS.85%29.aspx說GdipCreateBitmapFromHBITMAP()
對應於Bitmap::Bitmap()
構造函數的HBITMAP
和HPALETTE
作爲參數。
在http://msdn.microsoft.com/en-us/library/ms536314%28VS.85%29.aspx此版本的Bitmap::Bitmap()
構造函數的文檔中有這樣一段話:
您有責任刪除GDI的位圖和GDI調色板。但是,直到GDI + Bitmap :: Bitmap對象被刪除或超出範圍之後,才能刪除GDI位圖或GDI調色板。
不要傳遞給GDI +位圖::位圖構造函數當前(或之前)已選擇到設備上下文中的GDI位圖或GDI調色板。
此外,可以在用於C源代碼看到++ GDI +在GdiPlusBitmap.h的一部分,該Bitmap::Bitmap()
構造中的問題是本身爲從平坦API的GdipCreateBitmapFromHBITMAP()
函數的包裝:
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 +位圖。
因此,簡言之:
- 是否原始位手柄需要被周圍,直到淨位圖對象設置保存?
- GDI +函數
GdipCreateBitmapFromHBITMAP()
是否創建源位圖的副本或僅保留原始句柄? - 爲什麼我不應該使用先前選擇到設備上下文中的HBITMAP?
同意衝突。本地位圖構造函數文檔必須是僞造的。 – 2010-06-17 05:15:46