private IntPtr CreateCompatibleDIB(IntPtr hdc, IntPtr hpal, int ulWidth, int ulHeight, ref IntPtr ppvBits) { if (hdc == IntPtr.Zero) { throw new ArgumentNullException("hdc"); } IntPtr zero = IntPtr.Zero; System.Drawing.NativeMethods.BITMAPINFO_FLAT pbmi = new System.Drawing.NativeMethods.BITMAPINFO_FLAT(); switch (System.Drawing.UnsafeNativeMethods.GetObjectType(new HandleRef(null, hdc))) { case 3: case 4: case 10: case 12: if (this.bFillBitmapInfo(hdc, hpal, ref pbmi)) { pbmi.bmiHeader_biWidth = ulWidth; pbmi.bmiHeader_biHeight = ulHeight; if (pbmi.bmiHeader_biCompression == 0) { pbmi.bmiHeader_biSizeImage = 0; } else if (pbmi.bmiHeader_biBitCount == 0x10) { pbmi.bmiHeader_biSizeImage = (ulWidth * ulHeight) * 2; } else if (pbmi.bmiHeader_biBitCount == 0x20) { pbmi.bmiHeader_biSizeImage = (ulWidth * ulHeight) * 4; } else { pbmi.bmiHeader_biSizeImage = 0; } pbmi.bmiHeader_biClrUsed = 0; pbmi.bmiHeader_biClrImportant = 0; zero = SafeNativeMethods.CreateDIBSection(new HandleRef(null, hdc), ref pbmi, 0, ref ppvBits, IntPtr.Zero, 0); Win32Exception exception = null; if (zero == IntPtr.Zero) { exception = new Win32Exception(Marshal.GetLastWin32Error()); } if (exception != null) { throw exception; } } return(zero); } throw new ArgumentException(System.Drawing.SR.GetString("DCTypeInvalid")); }
/// <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. 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.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); }