private unsafe void CreateDitherBrush() { Debug.Assert(_hbrushDither.IsNull, "Brush should not be recreated."); short *patternBits = stackalloc short[] { unchecked ((short)0xAAAA), unchecked ((short)0x5555), unchecked ((short)0xAAAA), unchecked ((short)0x5555), unchecked ((short)0xAAAA), unchecked ((short)0x5555), unchecked ((short)0xAAAA), unchecked ((short)0x5555) }; Gdi32.HBITMAP hbitmapTemp = Gdi32.CreateBitmap(8, 8, 1, 1, patternBits); Debug.Assert( !hbitmapTemp.IsNull, "could not create dither bitmap. Page selector UI will not be correct"); if (!hbitmapTemp.IsNull) { _hbrushDither = Gdi32.CreatePatternBrush(hbitmapTemp); Debug.Assert( !_hbrushDither.IsNull, "Unable to created dithered brush. Page selector UI will not be correct"); Gdi32.DeleteObject(hbitmapTemp); } }
internal unsafe MetafileDCWrapper(IntPtr hOriginalDC, Size size) { Debug.Assert(Gdi32.GetObjectType(hOriginalDC) == Gdi32.ObjectType.OBJ_ENHMETADC, "Why wrap a non-Enhanced MetaFile DC?"); if (size.Width < 0 || size.Height < 0) { throw new ArgumentException(SR.ControlMetaFileDCWrapperSizeInvalid, nameof(size)); } _hMetafileDC = hOriginalDC; _destRect = new RECT(0, 0, size.Width, size.Height); HDC = Gdi32.CreateCompatibleDC(IntPtr.Zero); int planes = Gdi32.GetDeviceCaps(HDC, Gdi32.DeviceCapability.PLANES); int bitsPixel = Gdi32.GetDeviceCaps(HDC, Gdi32.DeviceCapability.BITSPIXEL); _hBitmap = Gdi32.CreateBitmap(size.Width, size.Height, (uint)planes, (uint)bitsPixel, null); _hOriginalBmp = Gdi32.SelectObject(HDC, _hBitmap); }
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 = Gdi32.CreateBitmap(1, 1, 1, 1, null); 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); } var lpbmi = new Gdi32.BITMAPINFO { bmiHeader = new Gdi32.BITMAPINFOHEADER { biSize = (uint)sizeof(Gdi32.BITMAPINFOHEADER), biWidth = bmp.bmWidth, biHeight = bmp.bmHeight, biPlanes = 1, biBitCount = bmp.bmBitsPixel, biCompression = Gdi32.BI.RGB }, bmiColors = new byte[Gdi32.BITMAPINFO.MaxColorSize * 4] }; // Include the palette for 256 color bitmaps long iColors = 1 << (bmp.bmBitsPixel * bmp.bmPlanes); if (iColors <= 256) { byte[] aj = ArrayPool <byte> .Shared.Rent(sizeof(Gdi32.PALETTEENTRY) * 256); try { Gdi32.GetSystemPaletteEntries(hdcSrc, 0, (uint)iColors, aj); fixed(byte *pcolors = lpbmi.bmiColors) { fixed(byte *ppal = aj) { Gdi32.RGBQUAD * prgb = (Gdi32.RGBQUAD *)pcolors; Gdi32.PALETTEENTRY *lppe = (Gdi32.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; } } } } finally { ArrayPool <byte> .Shared.Return(aj); } } // 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 = Gdi32.GetDIBits( hdcSrc, hBitmap, 0, (uint)bmp.bmHeight, lpBits, ref lpbmi, Gdi32.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 = Gdi32.StretchDIBits( hdcDest, xDest, yDest, cxDest, cyDest, 0, 0, bmp.bmWidth, bmp.bmHeight, lpBits, ref lpbmi, Gdi32.DIB.RGB_COLORS, Gdi32.ROP.SRCCOPY); if (iRet == NativeMethods.GDI_ERROR) { return(false); } } finally { Gdi32.DeleteObject(hNullBitmap); } return(true); }