Changing the Windows Mouse Cursor in XNA

aero_arrow

Background

For anyone who is looking to develop a mouse-based game for Windows using the XNA framework, it’s pretty critical to be able to change your mouse cursor in game. The first method is to hide the mouse cursor and draw a custom texture in place of it – but anyone who is developing a game that might not be running at a full 60 frames/sec will know that this is does not work well, as it results in a very slow and unresponsive mouse movement.

The Windows operating system is designed to give extremely responsive mouse movement no matter how slow your applications are running, so we’d like to harness this power in XNA while also giving us the power to change our cursors.

Overview

The following will allow you to change the windows cursor in XNA to any .cur or .ani file (full colour, animated, just like through the Windows Control Panel). This is done by changing the cursor of the windows forms handle for the XNA window. To load full colour and animated cursors, we will use the IntPtr LoadCursorFromFile(string) method from user32.dll, as suggested by Hans Passant.

Step 1: Add References

  • Add the “System.Windows.Forms” reference to your game project. Do this by right clicking on the References folder in the Solution Explorer for your project and select “Add Reference…”. It can be found under the “.Net” tab.
  • You will need to include the following namespaces:
using System.Windows.Forms;
// For the NativeMethods helper class:
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Reflection;

Step 2: Add your Custom Cursor

  • Add cursor to your project (let’s say it’s called “cursor.ani” and you put it in the “Content\Cursors” directory).
  • Go to the Properties of this cursor in your Solution Explorer and set the “Build Action” to “None” and “Copy to Output Directory” to “Copy if newer”.

Step 3: Loading The Cursor

You will need something like the following helper method to load your full colour animated cursor into a handle that Windows Forms can use:

// Thanks Hans Passant!
// http://stackoverflow.com/questions/4305800/using-custom-colored-cursors-in-a-c-windows-application
static class NativeMethods
{
    public static Cursor LoadCustomCursor(string path)
    {
        IntPtr hCurs = LoadCursorFromFile(path);
        if (hCurs == IntPtr.Zero) throw new Win32Exception();
        var curs = new Cursor(hCurs);
        // Note: force the cursor to own the handle so it gets released properly
        var fi = typeof(Cursor).GetField("ownHandle", BindingFlags.NonPublic | BindingFlags.Instance);
        fi.SetValue(curs, true);
        return curs;
    }
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr LoadCursorFromFile(string path);
}

Step 4: Changing the Cursor

First, set the mouse to visible:

this.IsMouseVisible = true; // in your Game class

Next, load your cursor using the above static helper method:

Cursor myCursor = NativeMethods.LoadCustomCursor(@"Content\Cursors\cursor.ani");

Now load up the window handle that will let you change the window’s cursor:

Form winForm = (Form)Form.FromHandle(this.Window.Handle);

Simply do the following to change the cursor:

winForm.Cursor = myCursor;

That’s it! Happy game dev-ing!

Tags: , , , ,

10 Responses to “Changing the Windows Mouse Cursor in XNA”

  • bonbon says:

    I can’t use this “using System.Windows.Forms”
    It said Windows was not included in System, although I was still using System.Windows.Forms in other projects (not windows games ones).

  • Hey bonbon,

    I think I get the same error message if I do not include the System.Windows.Forms assembly reference in the project. To include this reference go to the Solution Explorer and under your main game project right click on the References folder and select “Add Reference…”. Then go to the “.Net” tab and select “System.Windows.Forms”. That should fix the problem.

    Allen

  • bonbon says:

    Yeah it actually fixed the previous problem.
    Now it says
    “Cannot autodetect which importer to use for “cursor.cur”. There are no importers which handle this file type. Specify the importer that handles this file type in your project.”
    I’m new in VS and XNA then, have no ideas what to do with this lol.
    Thanks for the last reply, that helped a lot :D

  • bonbon says:

    Wait a sec LOL!!!
    Sorry sorry I correct it right after replying.
    All I forgot to set is “Build Action” to “None”.

  • bonbon says:

    Hey Allen,
    Sorry for posting too many replies…
    All works fine except for “Image format is not valid.The file may be corrupted”.
    This happens even when I use a windows cursor found in Windows/Cursors.

  • cash3wz says:

    Bonbon, I’ve got the same problem. I load a working cursor but I get the ‘image not valid error’.

  • bonbon says:

    I’ve just had a look at MSDN’s note about Cursor class in msdn.microsoft.com. Here’s what I found: “The Cursor class does not support animated cursors (.ani files) or cursors with colors other than black and white.”
    I’ve tried to create a new black and white cursor and it actually worked fine…

  • Hmm… I already knew about not supporting animated cursors (thanks for confirming this), but I’m surprised by colour being a problem for you. Maybe no more than 256 colours are supported? I tested using the “harrow.cur” which has blue colouring at the bottom — It seems to work fine. Try limiting colour pallet of your cursors to 256 colours and also make sure they’re 32×32 or some other standard size.

  • bonbon says:

    Yeah… I’ve tried a cursor with 256 colors and 32×32 size, it loaded but instead of showing a colorful cursor it just shown a black one (and no other colors rather than black and white).
    Maybe I missed something?

  • Aha! You’re completely right, bonbon. The Cursor constructor that takes a the file path seems to be very limited. I found a post on StackOverflow that address this exact issue:

    http://stackoverflow.com/questions/4305800/using-custom-colored-cursors-in-a-c-windows-application

    I’ve updated the post to use Hans’ method of loading the cursors. Now you should be able to use full colour animated cursors no problem.

    Thanks for the comments! I’m happy we were able to get a good, solid tutorial out of this!

    Allen

Leave a Reply