VLV
VLV

Reputation: 187

How to use a custom cursor?

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

Upvotes: 7

Views: 9745

Answers (2)

VLV
VLV

Reputation: 187

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

Upvotes: 9

xMRi
xMRi

Reputation: 15375

  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...

Upvotes: 1

Related Questions