http://msdn.microsoft.com/en-us/library/k061we7x%28VS.80%29.aspxImage.FromHbitmap()
のドキュメントから:
FromHbitmapメソッドは、GDIビットマップのコピーを作成します。そのため、新しいイメージを作成した直後に、GDIDeleteObjectメソッドを使用して着信GDIビットマップを解放できます。
これは、ビットマップインスタンスが作成されるとすぐに、DeleteObjectを使用してビットマップハンドルをすぐに削除できることを明確に示しています。
ただし、with 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 + Bitmap :: Bitmapコンストラクターに、デバイスコンテキストで現在(または以前に)選択されているGDIビットマップまたはGDIパレットを渡さないでください。
さらに、GdiPlusBitmap.hのGDI+のC++部分のソースコードで、問題のコンストラクター自体がフラットAPIの関数Bitmap::Bitmap()
のラッパーであることがわかります。GdipCreateBitmapFromHBITMAP()
inline
Bitmap::Bitmap(
IN HBITMAP hbm,
IN HPALETTE hpal
)
{
GpBitmap *bitmap = NULL;
lastResult = DllExports::GdipCreateBitmapFromHBITMAP(hbm, hpal, &bitmap);
SetNativeImage(bitmap);
}
私が簡単に理解できないのはGdipCreateBitmapFromHBITMAP()
、この機能のコアである実装ですが、ドキュメントの2つの注釈は矛盾しているようです。.Netのドキュメントには、ビットマップハンドルをすぐに削除できると記載されており、GDI +のドキュメントには、ラッピングオブジェクトが削除されるまでビットマップハンドルを保持する必要があると記載されていますが、どちらも同じGDI+関数に基づいています。
さらに、GDI +ドキュメントは、デバイスコンテキストで現在または以前に選択されたソースHBITMAPを使用しないように警告しています。現在、ビットマップがデバイスコンテキストで選択されるべきではない理由は理解できますが、以前にデバイスコンテキストで選択されたビットマップを使用することに対する警告がある理由は理解できません。これにより、標準のGDIを使用してメモリ内に作成されたGDI+ビットマップを使用できなくなるようです。
したがって、要約すると:
- .Net Bitmapオブジェクトが破棄されるまで、元のビットマップハンドルを保持する必要がありますか?
- GDI +関数は
GdipCreateBitmapFromHBITMAP()
、ソースビットマップのコピーを作成しますか、それとも単にオリジナルへのハンドルを保持しますか? - 以前にデバイスコンテキストに選択されたHBITMAPを使用しないのはなぜですか?