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# - マウス カーソルの画像をキャプチャしますが、私の問題に対する解決策もありません。これを読んでくれてありがとう。

4

1 に答える 1