SoFunction
Updated on 2025-03-07

C# Customize mouse cursor for desktop applications

Sometimes, a custom mouse cursor can add a lot of color to your program. Here is a description of how to customize the mouse cursor in the .net desktop program. Since the desktop programs of .net are divided into WinForm and WPF, we will introduce them separately here.

WinForm Program

For WinForm programs, you can modify the cursor by modifying the properties. If we have a cursor file, you can directly implement the custom cursor through the following code:

 = new Cursor("");

But this method is not the focus of this article. This article mainly introduces how to draw the cursor yourself, which will have more controllability and flexibility.

To create a custom cursor, you must first define a cursor structure.ICONINFO, its .net version is as follows:

    public struct IconInfo
    {
        public bool fIcon;
        public int xHotspot;
        public int yHotspot;
        public IntPtr hbmMask;
        public IntPtr hbmColor;
    }

Then passGetIconInfo and CreateIconIndirectTwo functions to synthesize the cursor. The complete code is as follows:

    public class CursorHelper
    {
        static class NativeMethods
        {
            public struct IconInfo
            {
                public bool fIcon;
                public int xHotspot;
                public int yHotspot;
                public IntPtr hbmMask;
                public IntPtr hbmColor;
            }

            [DllImport("")]
            public static extern IntPtr CreateIconIndirect(ref IconInfo icon);


            [DllImport("")]
            [return: MarshalAs()]
            public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
        }

        public static Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot)
        {
            var icon = new 
            {
                xHotspot = xHotSpot,
                yHotspot = yHotSpot,
                fIcon = false
            };

            ((), ref icon);
            return new Cursor((ref icon));
        }
    }

The test code is:

    using (Bitmap bitmap = new Bitmap(21, 26))
    using (Graphics g = (bitmap))
    {
        (, 0, 0, 20, 25);
         = (bitmap, 3, 3);
    }

WPF Programs

As for WPF programs, they are very similar to WinForm programs. On the one hand, they can also write Cursor attributes to customize the cursor file through the cursor file.

As for drawing the cursor yourself, the above code can basically be reused, but it needs to be repackaged relatively. The complete code is as follows:

    public class CursorHelper
    {
        static class NativeMethods
        {
            public struct IconInfo
            {
                public bool fIcon;
                public int xHotspot;
                public int yHotspot;
                public IntPtr hbmMask;
                public IntPtr hbmColor;
            }

            [DllImport("")]
            public static extern SafeIconHandle CreateIconIndirect(ref IconInfo icon);

            [DllImport("")]
            public static extern bool DestroyIcon(IntPtr hIcon);

            [DllImport("")]
            [return: MarshalAs()]
            public static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);
        }

        [SecurityPermission(, UnmanagedCode = true)]
        class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
        {
            public SafeIconHandle()
                : base(true)
            {
            }

            protected override bool ReleaseHandle()
            {
                return (handle);
            }
        }

        static Cursor InternalCreateCursor( bitmap, int xHotSpot, int yHotSpot)
        {
            var iconInfo = new 
            {
                xHotspot = xHotSpot,
                yHotspot = yHotSpot,
                fIcon = false
            };

            ((), ref iconInfo);

            var cursorHandle = (ref iconInfo);
            return (cursorHandle);
        }

        public static Cursor CreateCursor(UIElement element, int xHotSpot = 0, int yHotSpot = 0)
        {
            (new Size(, ));
            (new Rect(new Point(), ));

            var renderTargetBitmap = new RenderTargetBitmap(
                (int), (int),
                96, 96, PixelFormats.Pbgra32);

            (element);

            var encoder = new PngBitmapEncoder();
            ((renderTargetBitmap));

            using (var memoryStream = new MemoryStream())
            {
                (memoryStream);
                using (var bitmap = new (memoryStream))
                {
                    return InternalCreateCursor(bitmap, xHotSpot, yHotSpot);
                }
            }
        }
    }

It should be noted that since it is used, it needs to be cited.

After encapsulation, UIElement can be directly passed into the self-drawn cursor. Thanks to WPF's powerful drawing function, it is very easy to draw beautiful cursors. The test code is as follows:

= (new UserControl1());

This is all about this article about C# customizing mouse cursors for desktop applications. I hope it will be helpful to everyone's learning and I hope everyone will support me more.