7

I'm trying to change the default OS cursor to a custom one. As of now, I'm only dealing with Windows. I got an image file with the cursor I want (.png, should I change format?). All in all, I've been searching and trying to simply change the cursor, with no success. Also, as of now I'm looking for the most simple solution, with as few line of codes as possible.

If relevant:
-I'm using a window created with SFML(2.1).
-The following compiles but makes no difference:

HCURSOR hCursor = LoadCursor(NULL, "path/filename.png");
SetCursor(hCursor);

So, I'm seeking the knowledge of the community, any ideas?

The following works :) It does however immediately revert back to default windows mouse:

HCURSOR hCursor = LoadCursorFromFile("path/filename.cur");
SetCursor(hCursor);

I found this LINK, which seems to be the same problem as mine.
I am however unable to apply the answer given in the link

HWND windowHandle;
int GCL_Hcursor = -12; //GCL_HCURSOR
HCURSOR hCursor = LoadCursorFromFile("Graphics/Cursors/Pointer_small.cur");
SetCursor(hCursor);
SetClassLong(windowHandle, GCL_Hcursor, (DWORD)hCursor);

I (obviously?) get:

uninitialized local variable 'windowHandle' used

General Grievance
  • 4,555
  • 31
  • 31
  • 45
VLV
  • 167
  • 1
  • 12
  • It's got to be a .cur or .ani file....use a Resource Editor or Graphics Package that supports that format....use LoadCursorFromFile if you want to load from a file....or put it in your "resources", and use LoadCursor to access that resource (via its "id"). .... http://msdn.microsoft.com/en-gb/library/windows/desktop/ms648392(v=vs.85).aspx – Colin Smith Aug 06 '14 at 21:48
  • Thanks :) It now works as for loading and displaying the cursor on screen :) It does disappear though – VLV Aug 06 '14 at 23:09
  • Why don't you simply hide the cursor (it's a member function of the sf::Window class) and display a sprite at the mouse position ? That's way simpler than to overried the OS cursor. – teh internets is made of catz Aug 10 '14 at 13:45
  • Input lag is terrible by doing so. By overriding OS cursor, there is no input lag even at low fps. – VLV Sep 12 '14 at 22:38

2 Answers2

7

After roughly 4 hours and 30 minutes trying to get a custom mouse working with SFML on Windows, I finally managed to accomplish a task for which I had expected to use no more than 5 to 10 minutes. As such, I leave here the answer to my very own question, since the internet was unable to provide it clean and clear to a noob like me. May it be useful to whoever may need it.

#include <SFML/Graphics.hpp>
#include <windows.h>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Simple Cursor Demonstration");

    // {This is what matters}
    { 
        sf::WindowHandle wHandle;
        wHandle = window.getSystemHandle();
        HCURSOR Cursor = LoadCursor(NULL, IDC_HAND); // IDC_ARROW IDC_WAIT IDC_HAND...  http://msdn.microsoft.com/en-us/library/ms648391%28v=vs.85%29.aspx
        //HCURSOR Cursor = LoadCursorFromFile("path/filename.cur"); //.cur or .ani
        SetCursor(Cursor);
        SetClassLongPtr(wHandle, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(Cursor));
    }


    // to prove it works, just move the mouse around
    // not 100% sure the following actually proves it, but the above worked wonders on the project I wanted it for
    window.clear(sf::Color(sf::Color(0, 255, 0))); 
    window.display();
    sf::sleep(sf::milliseconds(3000));

    return 0; //I've read this line or equivalent is a good idea... :)
}

Sources:

-This solution was plundered from around the internet, but mainly from Overcomplicated for a Noob ,which was also mentioned by someone who deleted their answer. While being [Overcomplicated for a Noob], it does seem to provide great information on how to properly implement custom cursors on a program, as well as how to do it on apple OS thingy instead
-This was also useful.
-colinsmith mentioned the cursor file must be .cur or .ani, .png does indeed not work

VLV
  • 167
  • 1
  • 12
1
  1. Creating a Cursor from a Bitmap is described here http://www.codeproject.com/Articles/5220/Creating-a-color-cursor-from-a-bitmap Converting a png into a Bitmap can be done easily with CImage. Simply load the PNG and Detach the HBITMAP. But a Bitmap alone is no Cursor.
  2. Cursors are set by the window that receive WM_SETCURSOR. So "replacing" a specific Cursor will not work. You have to intercept the WM_SETCURSOR message to change the cursor that should be returned.
  3. Your Edit2 is wrong because you Need a valid window handle to change the cursor in the class of a window. But this will never work, ifthe window handles the Cursor by ist own (see 2)

PS: It would be better to inform yourself how Windows handles Cursors before you ask how to Change it globally...

xMRi
  • 14,982
  • 3
  • 26
  • 59