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