PuerNoctis PuerNoctis - 13 days ago 7
C# Question

WPF and custom cursors

I want to set a custom cursor within my WPF application. Originally I had a .png file, which i converted to .ico, but since I didn't find any way to set an .ico file as a cursor in WPF, I tried to do this with a proper .cur file.

I have created such an .cur file using Visual Studio 2013 (New Item -> Cursor File). The cursor is a coloured 24-bit image and its build-type is "Resource".

I accquire the resource stream with this:

var myCur = Application.GetResourceStream(new Uri("pack://application:,,,/mycur.cur")).Stream;


This code is able to retrieve the stream, so
myCur
is NOT null aferwards.

When trying to create the cursor with

var cursor = new System.Windows.Input.Cursor(myCur);


the default cursor
Cursors.None
is returned and not my custom cursor. So there seems to be a problem with that.

Can anybody tell me why the .ctor has problems with my cursor stream? The file was created using VS2013 itself, so I'd assume that the .cur file is correctly formatted. Alternatively: If someone knows how to load a .ico file as a cursor in WPF, I'd be very happy and very grateful.

EDIT: Just tried the same with a fresh new .cur file from VS2013 (8bpp) in case adding a new palette has screwed the image format. Same result. The .ctor of
System.Windows.Input.Cursor
can't even create a proper cursor from the 'fresh' cursor file.

Answer

Note: Possible dupe of Custom cursor in WPF?

Essentially you have to use the win32 method CreateIconIndirect

// FROM THE ABOVE LINK
public class CursorHelper
{
    private struct IconInfo
    {
        public bool fIcon;
        public int xHotspot;
        public int yHotspot;
        public IntPtr hbmMask;
        public IntPtr hbmColor;
    }

    [DllImport("user32.dll")]
    private static extern IntPtr CreateIconIndirect(ref IconInfo icon);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);


    public static Cursor CreateCursor(System.Drawing.Bitmap bmp, int xHotSpot, int yHotSpot)
    {
        IconInfo tmp = new IconInfo();
        GetIconInfo(bmp.GetHicon(), ref tmp);
        tmp.xHotspot = xHotSpot;
        tmp.yHotspot = yHotSpot;
        tmp.fIcon = false;

        IntPtr ptr = CreateIconIndirect(ref tmp);
        SafeFileHandle handle = new SafeFileHandle(ptr, true);
        return CursorInteropHelper.Create(handle);
    }
}