/// <summary> /// Gets the position and Bitmap of the system cursor. /// </summary> /// <param name="point"><code>ref</code> parameter, only to return a second value.</param> /// <returns>The current Icon of the cursor</returns> public static Bitmap CaptureImageCursor(ref Point point) { var cursorInfo = new Native.CURSORINFO(); cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); if (!Native.GetCursorInfo(out cursorInfo)) return null; if (cursorInfo.flags != Native.CURSOR_SHOWING) return null; IntPtr hicon = Native.CopyIcon(cursorInfo.hCursor); if (hicon == IntPtr.Zero) return null; Native.ICONINFO iconInfo; if (!Native.GetIconInfo(hicon, out iconInfo)) return null; point.X = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot); point.Y = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot); using (Bitmap maskBitmap = Image.FromHbitmap(iconInfo.hbmMask)) { //Is this a monochrome cursor? if (maskBitmap.Height == maskBitmap.Width * 2) { var resultBitmap = new Bitmap(maskBitmap.Width, maskBitmap.Width); Graphics desktopGraphics = Graphics.FromHwnd(Native.GetDesktopWindow()); IntPtr desktopHdc = desktopGraphics.GetHdc(); IntPtr maskHdc = Native.CreateCompatibleDC(desktopHdc); IntPtr oldPtr = Native.SelectObject(maskHdc, maskBitmap.GetHbitmap()); using (Graphics resultGraphics = Graphics.FromImage(resultBitmap)) { IntPtr resultHdc = resultGraphics.GetHdc(); // These two operation will result in a black cursor over a white background. // Later in the code, a call to MakeTransparent() will get rid of the white background. Native.BitBlt(resultHdc, 0, 0, 32, 32, maskHdc, 0, 32, CopyPixelOperation.SourceCopy); Native.BitBlt(resultHdc, 0, 0, 32, 32, maskHdc, 0, 0, CopyPixelOperation.SourceInvert); resultGraphics.ReleaseHdc(resultHdc); } IntPtr newPtr = Native.SelectObject(maskHdc, oldPtr); Native.DeleteObject(newPtr); Native.DeleteDC(maskHdc); desktopGraphics.ReleaseHdc(desktopHdc); // Remove the white background from the BitBlt calls, // resulting in a black cursor over a transparent background. resultBitmap.MakeTransparent(Color.White); return resultBitmap; } } Icon icon = Icon.FromHandle(hicon); return icon.ToBitmap(); }
/// <summary> /// Gets the position and Bitmap of the system cursor. /// </summary> /// <param name="point"><code>ref</code> parameter, only to return a second value.</param> /// <returns>The current Icon of the cursor</returns> public static Bitmap CaptureImageCursor(ref Point point) { var cursorInfo = new Native.CURSORINFO(); cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); if (!Native.GetCursorInfo(out cursorInfo)) return null; if (cursorInfo.flags != Native.CURSOR_SHOWING) return null; IntPtr hicon = Native.CopyIcon(cursorInfo.hCursor); if (hicon == IntPtr.Zero) return null; Native.ICONINFO iconInfo; if (!Native.GetIconInfo(hicon, out iconInfo)) return null; point.X = cursorInfo.ptScreenPos.x - ((int)iconInfo.xHotspot); point.Y = cursorInfo.ptScreenPos.y - ((int)iconInfo.yHotspot); try { using (Bitmap maskBitmap = Image.FromHbitmap(iconInfo.hbmMask)) { //Is this a monochrome cursor? //if (maskBitmap.Height == maskBitmap.Width * 2) if (maskBitmap.Height == maskBitmap.Width * 2 && iconInfo.hbmColor == IntPtr.Zero) { var resultBitmap = new Bitmap(maskBitmap.Width, maskBitmap.Width); using (Graphics desktopGraphics = Graphics.FromHwnd(Native.GetDesktopWindow())) { IntPtr desktopHdc = desktopGraphics.GetHdc(); IntPtr maskHdc = Native.CreateCompatibleDC(desktopHdc); IntPtr oldPtr = Native.SelectObject(maskHdc, maskBitmap.GetHbitmap()); using (Graphics resultGraphics = Graphics.FromImage(resultBitmap)) { IntPtr resultHdc = resultGraphics.GetHdc(); // These two operation will result in a black cursor over a white background. // Later in the code, a call to MakeTransparent() will get rid of the white background. // They take two pieces from a single image and merge into one. //Bottom part Native.BitBlt(resultHdc, 0, 0, resultBitmap.Width, resultBitmap.Height, maskHdc, 0, resultBitmap.Height, CopyPixelOperation.SourceCopy); //SourceCopy //Top part. Native.BitBlt(resultHdc, 0, 0, resultBitmap.Width, resultBitmap.Height, maskHdc, 0, 0, CopyPixelOperation.PatInvert); //SourceInvert //BUG: It still don't take into account the background color (from the desktop) with the I-bean cursor, the one that inverts its color. resultGraphics.ReleaseHdc(resultHdc); } IntPtr newPtr = Native.SelectObject(maskHdc, oldPtr); Native.DeleteObject(newPtr); Native.DeleteDC(maskHdc); desktopGraphics.ReleaseHdc(desktopHdc); } // Remove the white background from the BitBlt calls, // resulting in a black cursor over a transparent background. resultBitmap.MakeTransparent(Color.White); return resultBitmap; } } } catch (Exception ex) { LogWriter.Log(ex, "Impossible to get the icon."); } Icon icon = Icon.FromHandle(hicon); return icon.ToBitmap(); }