Esempio n. 1
0
            // bFillColorTable
            //
            // Initialize the color table of the BITMAPINFO pointed to by pbmi.  Colors
            // are set to the current system palette.
            //
            // Note: call only valid for displays of 8bpp or less.
            //
            // Returns:
            //   TRUE if successful, FALSE otherwise.
            //
            // History:
            //  23-Jan-1996 -by- Gilman Wong [gilmanw]
            // Wrote it.
            //
            //  15-Nov-2000 -by- Chris Anderson [chrisan]
            // Ported it to C#
            //
            private unsafe bool bFillColorTable(IntPtr hdc, IntPtr hpal, ref NativeMethods.BITMAPINFO_FLAT pbmi)
            {
                bool bRet = false;

                byte[] aj = new byte[sizeof(NativeMethods.PALETTEENTRY) * 256];
                int    i, cColors;

                fixed(byte *pcolors = pbmi.bmiColors)
                {
                    fixed(byte *ppal = aj)
                    {
                        NativeMethods.RGBQUAD *     prgb = (NativeMethods.RGBQUAD *)pcolors;
                        NativeMethods.PALETTEENTRY *lppe = (NativeMethods.PALETTEENTRY *)ppal;


                        cColors = 1 << pbmi.bmiHeader_biBitCount;
                        if (cColors <= 256)
                        {
                            Debug.WriteLineIf(DoubleBuffering.TraceVerbose, "8 bit or less...");

                            // NOTE : Didn't port "MyGetPaletteEntries" as it is only
                            //      : for 4bpp displays, which we don't work on anyway.
                            IntPtr palRet;
                            IntPtr palHalftone = IntPtr.Zero;
                            if (hpal == IntPtr.Zero)
                            {
                                Debug.WriteLineIf(DoubleBuffering.TraceVerbose, "using halftone palette...");
                                palHalftone = Graphics.GetHalftonePalette();
                                palRet      = SafeNativeMethods.GetPaletteEntries(new HandleRef(null, palHalftone), 0, cColors, aj);
                            }
                            else
                            {
                                Debug.WriteLineIf(DoubleBuffering.TraceVerbose, "using custom palette...");
                                palRet = SafeNativeMethods.GetPaletteEntries(new HandleRef(null, hpal), 0, cColors, aj);
                            }
                            if (palRet != IntPtr.Zero)
                            {
                                for (i = 0; i < cColors; i++)
                                {
                                    prgb[i].rgbRed      = lppe[i].peRed;
                                    prgb[i].rgbGreen    = lppe[i].peGreen;
                                    prgb[i].rgbBlue     = lppe[i].peBlue;
                                    prgb[i].rgbReserved = 0;
                                }

                                bRet = true;
                            }
                            else
                            {
                                Debug.WriteLine("bFillColorTable: MyGetSystemPaletteEntries failed\n");
                            }
                        }
                    }
                }

                return(bRet);
            }
        /// <summary>
        /// Initialize the color table of the BITMAPINFO pointed to by pbmi. Colors
        /// are set to the current system palette.
        ///
        /// Note: call only valid for displays of 8bpp or less.
        /// </summary>
        /// <returns>True is successful, false otherwise.</returns>
        private unsafe bool FillColorTable(IntPtr hdc, IntPtr hpal, ref NativeMethods.BITMAPINFO_FLAT pbmi)
        {
            byte[] aj = new byte[sizeof(NativeMethods.PALETTEENTRY) * 256];

            fixed(byte *pcolors = pbmi.bmiColors)
            {
                fixed(byte *ppal = aj)
                {
                    NativeMethods.RGBQUAD *     prgb = (NativeMethods.RGBQUAD *)pcolors;
                    NativeMethods.PALETTEENTRY *lppe = (NativeMethods.PALETTEENTRY *)ppal;

                    int cColors = 1 << pbmi.bmiHeader_biBitCount;

                    if (cColors <= 256)
                    {
                        // Note: we don't support 4bpp displays.
                        uint   palRet;
                        IntPtr palHalftone = IntPtr.Zero;
                        if (hpal == IntPtr.Zero)
                        {
                            palHalftone = Graphics.GetHalftonePalette();
                            palRet      = SafeNativeMethods.GetPaletteEntries(new HandleRef(null, palHalftone), 0, cColors, aj);
                        }
                        else
                        {
                            palRet = SafeNativeMethods.GetPaletteEntries(new HandleRef(null, hpal), 0, cColors, aj);
                        }

                        if (palRet != 0)
                        {
                            for (int i = 0; i < cColors; i++)
                            {
                                prgb[i].rgbRed      = lppe[i].peRed;
                                prgb[i].rgbGreen    = lppe[i].peGreen;
                                prgb[i].rgbBlue     = lppe[i].peBlue;
                                prgb[i].rgbReserved = 0;
                            }

                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
            // ported form VB6 (Ctls\PortUtil\StdCtl.cpp:6176)
            private unsafe bool DICopy(IntPtr hdcDest, IntPtr hdcSrc, RECT rect, bool bStretch)
            {
                long i;

                // Get the bitmap from the DC by selecting in a 1x1 pixel temp bitmap
                IntPtr hNullBitmap = SafeNativeMethods.CreateBitmap(1, 1, 1, 1, IntPtr.Zero);

                if (hNullBitmap == IntPtr.Zero)
                {
                    return(false);
                }

                try
                {
                    IntPtr hBitmap = Gdi32.SelectObject(hdcSrc, hNullBitmap);
                    if (hBitmap == IntPtr.Zero)
                    {
                        return(false);
                    }

                    // Restore original bitmap
                    Gdi32.SelectObject(hdcSrc, hBitmap);

                    if (!Gdi32.GetObjectW(hBitmap, out Gdi32.BITMAP bmp))
                    {
                        return(false);
                    }

                    NativeMethods.BITMAPINFO_FLAT lpbmi = new NativeMethods.BITMAPINFO_FLAT
                    {
                        bmiHeader_biSize          = Marshal.SizeOf <NativeMethods.BITMAPINFOHEADER>(),
                        bmiHeader_biWidth         = bmp.bmWidth,
                        bmiHeader_biHeight        = bmp.bmHeight,
                        bmiHeader_biPlanes        = 1,
                        bmiHeader_biBitCount      = (short)bmp.bmBitsPixel,
                        bmiHeader_biCompression   = NativeMethods.BI_RGB,
                        bmiHeader_biSizeImage     = 0,           //Not needed since using BI_RGB
                        bmiHeader_biXPelsPerMeter = 0,
                        bmiHeader_biYPelsPerMeter = 0,
                        bmiHeader_biClrUsed       = 0,
                        bmiHeader_biClrImportant  = 0,
                        bmiColors = new byte[NativeMethods.BITMAPINFO_MAX_COLORSIZE * 4]
                    };

                    // Include the palette for 256 color bitmaps
                    long iColors = 1 << (bmp.bmBitsPixel * bmp.bmPlanes);
                    if (iColors <= 256)
                    {
                        byte[] aj = new byte[Marshal.SizeOf <NativeMethods.PALETTEENTRY>() * 256];
                        SafeNativeMethods.GetSystemPaletteEntries(hdcSrc, 0, (int)iColors, aj);

                        fixed(byte *pcolors = lpbmi.bmiColors)
                        {
                            fixed(byte *ppal = aj)
                            {
                                NativeMethods.RGBQUAD *     prgb = (NativeMethods.RGBQUAD *)pcolors;
                                NativeMethods.PALETTEENTRY *lppe = (NativeMethods.PALETTEENTRY *)ppal;

                                // Convert the palette entries to RGB quad entries
                                for (i = 0; i < (int)iColors; i++)
                                {
                                    prgb[i].rgbRed   = lppe[i].peRed;
                                    prgb[i].rgbBlue  = lppe[i].peBlue;
                                    prgb[i].rgbGreen = lppe[i].peGreen;
                                }
                            }
                        }
                    }

                    // Allocate memory to hold the bitmap bits
                    long   bitsPerScanLine  = bmp.bmBitsPixel * (long)bmp.bmWidth;
                    long   bytesPerScanLine = (bitsPerScanLine + 7) / 8;
                    long   totalBytesReqd   = bytesPerScanLine * bmp.bmHeight;
                    byte[] lpBits           = new byte[totalBytesReqd];

                    // Get the bitmap bits
                    int diRet = SafeNativeMethods.GetDIBits(hdcSrc, hBitmap, 0, bmp.bmHeight, lpBits,
                                                            ref lpbmi, NativeMethods.DIB_RGB_COLORS);
                    if (diRet == 0)
                    {
                        return(false);
                    }

                    // Set the destination coordiates depending on whether stretch-to-fit was chosen
                    int xDest, yDest, cxDest, cyDest;
                    if (bStretch)
                    {
                        xDest  = rect.left;
                        yDest  = rect.top;
                        cxDest = rect.right - rect.left;
                        cyDest = rect.bottom - rect.top;
                    }
                    else
                    {
                        xDest  = rect.left;
                        yDest  = rect.top;
                        cxDest = bmp.bmWidth;
                        cyDest = bmp.bmHeight;
                    }

                    // Paint the bitmap
                    int iRet = SafeNativeMethods.StretchDIBits(hdcDest,
                                                               xDest, yDest, cxDest, cyDest, 0, 0, bmp.bmWidth, bmp.bmHeight,
                                                               lpBits, ref lpbmi, NativeMethods.DIB_RGB_COLORS, NativeMethods.SRCCOPY);

                    if (iRet == NativeMethods.GDI_ERROR)
                    {
                        return(false);
                    }
                }
                finally
                {
                    Gdi32.DeleteObject(hNullBitmap);
                }

                return(true);
            }