4

如果我在截屏时使用 DrawIcon,它可以正确绘制带有蒙版的 I 型光标,但如果我想在任何图像上使用 DrawIcon,则蒙版不起作用。

此 DrawIcon 示例正常工作:

    public static Image CaptureRectangleNative(IntPtr handle, Rectangle rect, bool captureCursor = false)
    {
        if (rect.Width == 0 || rect.Height == 0)
        {
            return null;
        }

        IntPtr hdcSrc = NativeMethods.GetWindowDC(handle);
        IntPtr hdcDest = NativeMethods.CreateCompatibleDC(hdcSrc);
        IntPtr hBitmap = NativeMethods.CreateCompatibleBitmap(hdcSrc, rect.Width, rect.Height);
        IntPtr hOld = NativeMethods.SelectObject(hdcDest, hBitmap);
        NativeMethods.BitBlt(hdcDest, 0, 0, rect.Width, rect.Height, hdcSrc, rect.X, rect.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);

        if (captureCursor)
        {
            Point cursorOffset = CaptureHelpers.ScreenToClient(rect.Location);

            try
            {
                using (CursorData cursorData = new CursorData())
                {
                    cursorData.DrawCursorToHandle(hdcDest, cursorOffset);
                }
            }
            catch (Exception e)
            {
                DebugHelper.WriteException(e, "Cursor capture failed.");
            }
        }

        NativeMethods.SelectObject(hdcDest, hOld);
        NativeMethods.DeleteDC(hdcDest);
        NativeMethods.ReleaseDC(handle, hdcSrc);
        Image img = Image.FromHbitmap(hBitmap);
        NativeMethods.DeleteObject(hBitmap);

        return img;
    }

    // This function inside CursorData class
    public void DrawCursorToHandle(IntPtr hdcDest, Point cursorOffset)
    {
        if (IconHandle != IntPtr.Zero)
        {
            Point drawPosition = new Point(Position.X - cursorOffset.X, Position.Y - cursorOffset.Y);
            NativeMethods.DrawIcon(hdcDest, drawPosition.X, drawPosition.Y, IconHandle);
        }
    }

但是这个 DrawIcon 示例没有使用遮罩,因此 I 形图标变为白色,并且在白色背景中不可见:

    public void DrawCursorToImage(Image img, Point cursorOffset)
    {
        if (IconHandle != IntPtr.Zero)
        {
            Point drawPosition = new Point(Position.X - cursorOffset.X, Position.Y - cursorOffset.Y);

            using (Graphics g = Graphics.FromImage(img))
            {
                g.DrawIcon(Icon.FromHandle(IconHandle), drawPosition.X, drawPosition.Y);
            }
        }
    }

我想如果我不使用桌面 hdc,那么 DrawIcon 就没有使用蒙版。如何修复 DrawCursorToImage 方法以便它可以正确使用光标掩码?顺便说一句,我读了这篇文章:C# - Capturing the Mouse cursor image,它也没有解决我的问题。感谢您阅读本文。

4

1 回答 1

0

对 DrawCursorToImage 的这种修改应该可以使它起作用,但我无法真正解释它为什么起作用:

public void DrawCursorToImage(Image img, Point cursorOffset)
{
    if (IconHandle != IntPtr.Zero)
    {
        Point drawPosition = new Point(Position.X - cursorOffset.X, Position.Y - cursorOffset.Y);

        using (Graphics g = Graphics.FromImage(img))
        {
            IntPtr hdc = g.GetHdc();
            using (Graphics gfx = Graphics.FromHdc(hdc))
            {
                // For some reason it is necessary to redraw the image here
                gfx.DrawImage(img, 0, 0);
                gfx.DrawIcon(Icon.FromHandle(IconHandle), drawPosition.X, drawPosition.Y);
            }
            g.ReleaseHdc();
        }
    }
}
于 2020-01-13T22:15:59.557 回答