views:

861

answers:

5

I am using SetCursor to set the system cursor to my own image. The code looks something like this:

// member on some class
HCURSOR _cursor;

// at init time
_cursor = LoadCursorFromFile("somefilename.cur");

// in some function
SetCursor(_cursor);

When I do this the cursor does change, but on the first mouse move message it changes back to the default system arrow cursor. This is the only code in the project that is setting the cursor. What do I need to do to make the cursor stay the way I set it?

+3  A: 

You need to respond to the Windows message WM_SETCURSOR.

Mark Ransom
+2  A: 

You need to make your HCURSOR handle not go out of scope. When the mouse moves, windows messages start flying all over the place, and it will wipe out your handle (in the example above).

Make an HCURSOR a private member of the class, and use that handle when you call LoadCursor...() and SetCursor(). When you are done, do not forget to free it, and clean it up, or you will end up with a resource leak.

LarryF
+2  A: 

It seems that I have two options. The first is the one that Mark Ransom suggested here, which is to respond to the windows WM_SETCURSOR message and call SetCursor at that time based on where the mouse is. Normally windows will only send you WM_SETCURSOR when the cursor is over your window, so you would only set the cursor in your window.

The other option is to set the default cursor for the window handle at the same time as I call SetCursor. This changes the cursor set by the default handler to WM_SETCURSOR. That code would look something like this:

// defined somewhere
HWND windowHandle;
HCURSOR cursor;

SetCursor(cursor);
SetClassLong(windowHandle, GCL_HCURSOR, (DWORD)cursor);

If you use the second method you have to call both SetCursor and SetClassLong or your cursor will not update until the next mouse move.

Joe Ludwig
A: 

This behavior is intended to be this way. I think the most simple solution is: When creating your window class (RegisterClass || RegisterClassEx), set the WNDCLASS.hCursor || WNDCLASSEX.hCursor member to NULL.

Heinz Traub
A: 

This behavior is intended to be this way. I think the most simple solution is: When creating your window class (RegisterClass or RegisterClassEx), set the WNDCLASS.hCursor or WNDCLASSEX.hCursor member to NULL.

Heinz Traub