private IntPtr CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, int ulWidth, int ulHeight, ref IntPtr ppvBits) { if (hdc == IntPtr.Zero) { throw new ArgumentNullException("hdc"); } IntPtr hbmRet = IntPtr.Zero; NativeMethods.BITMAPINFO_FLAT pbmi = new NativeMethods.BITMAPINFO_FLAT(); // // Validate hdc. // int objType = UnsafeNativeMethods.GetObjectType(new HandleRef(null, hdc)); switch(objType) { case NativeMethods.OBJ_DC: case NativeMethods.OBJ_METADC: case NativeMethods.OBJ_MEMDC: case NativeMethods.OBJ_ENHMETADC: break; default: throw new ArgumentException(SR.GetString(SR.DCTypeInvalid)); } if (bFillBitmapInfo(hdc, hpal, ref pbmi)) { // // Change bitmap size to match specified dimensions. // pbmi.bmiHeader_biWidth = ulWidth; pbmi.bmiHeader_biHeight = ulHeight; if (pbmi.bmiHeader_biCompression == NativeMethods.BI_RGB) { pbmi.bmiHeader_biSizeImage = 0; } else { if ( pbmi.bmiHeader_biBitCount == 16 ) pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 2; else if ( pbmi.bmiHeader_biBitCount == 32 ) pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 4; else pbmi.bmiHeader_biSizeImage = 0; } pbmi.bmiHeader_biClrUsed = 0; pbmi.bmiHeader_biClrImportant = 0; // // Create the DIB section. Let Win32 allocate the memory and return // a pointer to the bitmap surface. // hbmRet = SafeNativeMethods.CreateDIBSection(new HandleRef(null, hdc), ref pbmi, NativeMethods.DIB_RGB_COLORS, ref ppvBits, IntPtr.Zero, 0); Win32Exception ex = null; if ( hbmRet == IntPtr.Zero ) { ex = new Win32Exception(Marshal.GetLastWin32Error()); #if DEBUG DumpBitmapInfo(ref pbmi); #endif } #if DEBUG if (DoubleBuffering.TraceVerbose) { DumpBitmapInfo(ref pbmi); } #endif if(ex!=null) { throw ex; } } return hbmRet; }
/// <summary> /// Create a DIB section with an optimal format w.r.t. the specified hdc. /// /// If DIB <= 8bpp, then the DIB color table is initialized based on the /// specified palette. If the palette handle is NULL, then the system /// palette is used. /// /// Note: The hdc must be a direct DC (not an info or memory DC). /// /// Note: On palettized displays, if the system palette changes the /// UpdateDIBColorTable function should be called to maintain /// the identity palette mapping between the DIB and the display. /// </summary> /// <returns>A valid bitmap handle if successful, IntPtr.Zero otherwise.</returns> private IntPtr CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, int ulWidth, int ulHeight, ref IntPtr ppvBits) { if (hdc == IntPtr.Zero) { throw new ArgumentNullException(nameof(hdc)); } IntPtr hbmRet = IntPtr.Zero; var pbmi = new NativeMethods.BITMAPINFO_FLAT(); // Validate hdc. Interop.Gdi32.ObjectType objType = Interop.Gdi32.GetObjectType(hdc); switch (objType) { case Interop.Gdi32.ObjectType.OBJ_DC: case Interop.Gdi32.ObjectType.OBJ_METADC: case Interop.Gdi32.ObjectType.OBJ_MEMDC: case Interop.Gdi32.ObjectType.OBJ_ENHMETADC: break; default: throw new ArgumentException(SR.DCTypeInvalid); } if (FillBitmapInfo(hdc, hpal, ref pbmi)) { // Change bitmap size to match specified dimensions. pbmi.bmiHeader_biWidth = ulWidth; pbmi.bmiHeader_biHeight = ulHeight; if (pbmi.bmiHeader_biCompression == NativeMethods.BI_RGB) { pbmi.bmiHeader_biSizeImage = 0; } else { if (pbmi.bmiHeader_biBitCount == 16) { pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 2; } else if (pbmi.bmiHeader_biBitCount == 32) { pbmi.bmiHeader_biSizeImage = ulWidth * ulHeight * 4; } else { pbmi.bmiHeader_biSizeImage = 0; } } pbmi.bmiHeader_biClrUsed = 0; pbmi.bmiHeader_biClrImportant = 0; // Create the DIB section. Let Win32 allocate the memory and return // a pointer to the bitmap surface. hbmRet = SafeNativeMethods.CreateDIBSection(new HandleRef(null, hdc), ref pbmi, NativeMethods.DIB_RGB_COLORS, ref ppvBits, IntPtr.Zero, 0); Win32Exception ex = null; if (hbmRet == IntPtr.Zero) { ex = new Win32Exception(Marshal.GetLastWin32Error()); } if (ex != null) { throw ex; } } return(hbmRet); }