C - Win32 - managing custom buttons.

Started by
20 comments, last by BrickInTheWall 13 years, 12 months ago
BTW what are you trying to achieve? It's not clear for me.
If you want to change the cursor if you move the pointer onto the widget:
Couldn't you simply register the GUI (window) class with the appropriate cursor? I think (not sure at all) that the cursor will be changed automatically to the cursor of the mouse-on-window.

And I don't get the 800-900 stuff.

And why are you doing this in WM_SETCURSOR?
Advertisement
As stated before the user is allowed to create little custom drawn buttons. I allow 100 of these buttons. Each time the user creates one the ID will be set to something between 800 and 900 and I can use this ID to access each button individually because I'm storing pointers to the button data in an array of 100 fields. I just want the cursor to change into a little "hand" when the user scrolls over any of the custom created buttons so he'll know that he can move it around. WM_SETCURSOR gets sent to my main window when the mouse input is not captured (MSDN). This could have a variaty of reasons, but one is also when the mouse goes over a child window. I check the ID to see if it is between 800 and 900 to see if it went over one of the user created buttons. I don't care which one of these buttons the user scrolls over, since I want the "hand cursor" on mouseover for any one of these buttons.
You might be right be right about the fact that I can register a cursor with a button, but honestly, I don't know. If I was able to do that, then that would of course be the easier alternative. I'm creating each button with the "button" class name. The only thing I'm doing differently is applying the BS_OWNERDRAW style and handling the WM_DRAWITEM message.
Is there a way to associate the cursor with a button? Otherwise I'll test what you suggested, that I use SetWindowLong to change the main cursor, and later change it back.
Fate fell short this time your smile fades in the summer.
The widget is just a window. If nothing else, use SetWindowLong on it (them) at startup.

BTW this is just adding one line. You could have tried a lot of variations in no time...
Thanks, I'll try that once I have time.
Fate fell short this time your smile fades in the summer.
Okay, I've got it working now using SetClassLong...but there is something I don't understand.

I use SetClassLong right after I create a button and I set it to use the hand cursor. Then in the WM_SETCURSOR message I use SetCursor...
At first it didn't work when I used this:
SetCursor(LoadCursor(GetModuleHandle(NULL), IDC_HAND));

Then I replaced GetModuleHandle(NULL) simply with NULL, and everything works.

In this example on MSDN: http://msdn.microsoft.com/en-us/library/ms648380%28VS.85%29.aspx

In "Creating a Cursor" at the beginning he creates to cursor handles, once with hInstance set to NULL and once to GetModuleHandle(NULL). I guess my question could be a bit more general. When do I use GetModuleHandle(NULL) and when do I simply pass NULL to an HINSTANCE parameter?
Fate fell short this time your smile fades in the summer.
Why do you have to handle WM_SETCURSOR at all?

Did you try not to handle it, and see if it works automatically?

BTW I use this:
win_state.cursor.Arrow 		= LoadCursor(NULL, IDC_ARROW); win_state.cursor.IBeam 		= LoadCursor(NULL, IDC_IBEAM); win_state.cursor.IBeam		= LoadCursor(NULL, IDC_IBEAM);win_state.cursor.sizeNWSE	= LoadCursor(NULL, IDC_SIZENWSE);win_state.cursor.sizeNESW	= LoadCursor(NULL, IDC_SIZENESW);win_state.cursor.sizeWE		= LoadCursor(NULL, IDC_SIZEWE);win_state.cursor.sizeNS		= LoadCursor(NULL, IDC_SIZENS);
right before any other window init/create functions. So you don't have to load again and again.

But try not to handle it please! (I'm curious if it works, but I can't try it ATM)
Ah yeh good idea loading it only once. And yea I tried not handling WM_SETCURSOR, it doesn't work then. But that's not all.
The kicker? If I press and hold on the button and move my mouse outside of the button, there I still have the hand symbol until I let go. Should this be happening?

EDIT: It only works when NOT handling WM_SETCURSOR if I change the cursor of my button class like this: SetClassLong(hButton, GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_HAND));

If I use this however: SetClassLong(hButton, GCL_HCURSOR, (LONG)LoadCursor(GetModuleHandle(NULL), IDC_HAND));
it doesn't work...can anyone explain to me why not? I'm not really confused as I don't really know anything about the HINSTANCE type, but if anyone could direct me to a source that would clarify things, I'd be happy.
Fate fell short this time your smile fades in the summer.
Sorry I don't get it.
Does it work or not?

BTW NULL means desktop. So (I'm not sure at all, and I'm not good with terms) you load the default cursors and stuff. If you pass a non zero valid instance handler, then I have no idea. I guess a regular window simply doesn't have those resources.

BTW I have no idea what you want with the GetModuleHandle.
What does MSDN tell you about that?
And if you are really curious, start a new thread instead.

But anyway, does it work the way I suggested or not?
Yes, I was confused as to why it wasen't working before, since your method seemed legit. Yet I don't get why NULL instead of GetModuleHandle(NULL) works. Oh well, maybe someone here can tell me.

Thanks for the help!
Fate fell short this time your smile fades in the summer.
edited prev post

This topic is closed to new replies.

Advertisement