public GhostCursor(Visual visual) { BitmapSource renderBitmap = CaptureScreen(visual); BitmapSource actualCursor = CaptureCursor(); byte[] pixels = GetBitmapPixels(actualCursor, (int)actualCursor.Width, (int)actualCursor.Height); WriteableBitmap wrbmp = new WriteableBitmap(renderBitmap); wrbmp.WritePixels(new Int32Rect(0, 0, (int)actualCursor.Width, (int)actualCursor.Height), pixels, actualCursor.PixelWidth * actualCursor.Format.BitsPerPixel / 8, 0); int width = renderBitmap.PixelWidth; int height = renderBitmap.PixelHeight; int stride = width * 4; // unfortunately, this byte array will get placed on the large object heap more than likely ... pixels = GetBitmapPixels(wrbmp, width, height); // -height specifies top-down bitmap BITMAPV5HEADER bInfo = new BITMAPV5HEADER(width, -height, 32); IntPtr ppvBits = IntPtr.Zero; BitmapHandle dibSectionHandle = null; try { dibSectionHandle = new BitmapHandle(CreateDIBSection(IntPtr.Zero, ref bInfo, DIB_RGB_COLORS, out ppvBits, IntPtr.Zero, 0)); // copy the pixels into the DIB section now ... Marshal.Copy(pixels, 0, ppvBits, pixels.Length); if (!dibSectionHandle.IsInvalid && ppvBits != IntPtr.Zero) { CreateCursor(width, height, dibSectionHandle); } } finally { if (dibSectionHandle != null) { dibSectionHandle.Dispose(); } } }
public GhostCursor(Visual visual) { BitmapSource renderBitmap = CaptureScreen(visual); BitmapSource actualCursor = CaptureCursor(); byte[] pixels = GetBitmapPixels(actualCursor, (int)actualCursor.Width, (int)actualCursor.Height); WriteableBitmap wrbmp = new WriteableBitmap(renderBitmap); wrbmp.WritePixels(new Int32Rect(0, 0, (int)actualCursor.Width, (int)actualCursor.Height), pixels, actualCursor.PixelWidth * actualCursor.Format.BitsPerPixel / 8, 0); int width = renderBitmap.PixelWidth; int height = renderBitmap.PixelHeight; int stride = width * 4; // unfortunately, this byte array will get placed on the large object heap more than likely ... pixels = GetBitmapPixels(wrbmp, width, height); // -height specifies top-down bitmap BITMAPV5HEADER bInfo = new BITMAPV5HEADER(width, -height, 32); IntPtr ppvBits = IntPtr.Zero; BitmapHandle dibSectionHandle = null; try { dibSectionHandle = new BitmapHandle(CreateDIBSection(IntPtr.Zero, ref bInfo, DIB_RGB_COLORS, out ppvBits, IntPtr.Zero, 0)); // copy the pixels into the DIB section now ... Marshal.Copy(pixels, 0, ppvBits, pixels.Length); if (!dibSectionHandle.IsInvalid && ppvBits != IntPtr.Zero) { CreateCursor(width, height, dibSectionHandle); } } finally { if (dibSectionHandle != null) { dibSectionHandle.Dispose(); } } }
private void CreateCursor(int width, int height, BitmapHandle dibSectionHandle) { BitmapHandle monoBitmapHandle = null; try { monoBitmapHandle = new BitmapHandle(CreateBitmap(width, height, 1, 1, IntPtr.Zero)); ICONINFO icon = new ICONINFO(); icon.IsIcon = false; icon.xHotspot = 0; icon.yHotspot = 0; icon.ColorBitmap = dibSectionHandle; icon.MaskBitmap = monoBitmapHandle; _iconHandle = CreateIconIndirect(ref icon); if (!_iconHandle.IsInvalid) { _ghostCursor = CursorInteropHelper.Create(_iconHandle); } } finally { // destroy the temporary mono bitmap now ... if (monoBitmapHandle != null) { monoBitmapHandle.Dispose(); } } }