Example #1
0
            // CreateCompatibleDIB
            //
            // 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.
            //
            // Returns:
            //   Valid bitmap handle if successful, NULL if error.
            //
            // History:
            //  23-Jan-1996 -by- Gilman Wong [gilmanw]
            // Wrote it.
            //
            //  15-Nov-2000 -by- Chris Anderson [chrisan]
            // Ported it to C#.
            //
            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.
                //
                if (UnsafeNativeMethods.GetObjectType(new HandleRef(null, hdc)) != NativeMethods.OBJ_DC)
                {
                    throw new ArgumentException("hdc");
                }

                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);

    #if DEBUG
                    if (DoubleBuffering.TraceVerbose)
                    {
                        DumpBitmapInfo(ref pbmi);
                    }
    #endif

                    if (hbmRet == IntPtr.Zero)
                    {
    #if DEBUG
                        DumpBitmapInfo(ref pbmi);
    #endif
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }
                }

                return(hbmRet);
            }