mIRC Home    About    Download    Register    News    Help

Print Thread
SetClassLong GCL_CURSOR on custom window #219413 17/03/10 08:16 PM
Joined: Jul 2004
Posts: 7
A
aschol Offline OP
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
A
Joined: Jul 2004
Posts: 7
I wrote a function to change the cursor when a user hovers over a certain area of a custom window, however to stop flickering I also set the cursor class of this window to NULL. The problem i'm having now is mIRC is setting EVERY custom window's cursor class to NULL
Here's my code:
Code:
int WINAPI SubWindow(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
{
        hTicker = (HWND)atol(data);
	if(IsWindow(hTicker)) 
	{
		SetClassLong(hTicker, GCL_HCURSOR, (LONG)NULL);
                // More unrelated code here
        }
        return 3;
}

Code:
int WINAPI mCursor(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
{
	HCURSOR hCurs;
	if (!lstrcmp(data, "Hand"))
		hCurs = LoadCursor(NULL, MAKEINTRESOURCE(32649));
	else if (!lstrcmp(data, "Arrow")) 
		hCurs = LoadCursor(NULL, IDC_ARROW);
	else {
		lstrcpy(data, "E_INVALIDPARAMETERS");
		return 3;
	}
	SetCursor(hCurs);
	lstrcpy(data, "S_OK");
	return 3;
}

Am I doing something wrong? The only thing I can think of is maybe i'm setting the global cursor class for custom windows to NULL instead of just for the one window. Please help frown

Re: SetClassLong GCL_CURSOR on custom window [Re: aschol] #219431 18/03/10 08:46 PM
Joined: Oct 2003
Posts: 3,918
A
argv0 Offline
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Your assumption is right. You're modifying the Window CLASS (SetClassLong). Take a look at "SetWindowLong" instead, which operates on HWNDs, not their WNDCLASSEX structures.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Re: SetClassLong GCL_CURSOR on custom window [Re: argv0] #219446 19/03/10 01:07 AM
Joined: Jul 2004
Posts: 7
A
aschol Offline OP
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
A
Joined: Jul 2004
Posts: 7
Oh I get it now, thanks for that. I did look in to SetWindowLong before SetClassLong but couldn't find anything about setting cursors though.

Unless you mean suclassing the window then using SetCursor when my window proc catches WM_MOUSEMOVE?

Thanks again

Re: SetClassLong GCL_CURSOR on custom window [Re: aschol] #219448 19/03/10 01:55 AM
Joined: Oct 2003
Posts: 3,918
A
argv0 Offline
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
If it's not available for SetWindowLong then it may not be possible to set on a per-window basis, in which case you would probably need to subclass the window, yes.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Re: SetClassLong GCL_CURSOR on custom window [Re: argv0] #219460 19/03/10 01:47 PM
Joined: Jul 2004
Posts: 7
A
aschol Offline OP
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
A
Joined: Jul 2004
Posts: 7
So i've been researching this for a few hours now to no avail, if anybody else is interested in this here is the solution I came up with:
Code:
HCURSOR hDefCursor;

case WM_MOUSEMOVE:
{
	if (!bHover)
	{
		bHover = TRUE;
                
                // Set class cursor to NULL when cursor is over the window
		SetClassLong(hwnd, GCL_HCURSOR, (LONG)NULL);


		lstrcpy(mData, "/.signal -n tick_mouse_enter");
		SendMessage(hmIRC, WM_MCOMMAND, 0, 0);

		SetTimer(hwnd, MOUSE_TIMER, 1, NULL);
	}
                // More Unrelated Code
}
break;
case WM_TIMER: 
{
	if ((int)wParam == MOUSE_TIMER)
	{
		GetCursorPos(&pt);
		GetWindowRect(hwnd, &rM);

		if(!PtInRect(&rM, pt))
		{
		    bHover = FALSE;

                    // Set class cursor back to arrow when the cursor leaves the window
		    hDefCursor = LoadCursor(NULL, IDC_ARROW);
		    SetClassLong(hwnd, GCL_HCURSOR, (LONG)hDefCursor);

		    KillTimer(hwnd, MOUSE_TIMER);
	
		    lstrcpy(mData, "/.signal -n tick_mouse_leave");
		    SendMessage(hmIRC, WM_MCOMMAND, 0, 0);
		}
	}
}
break;

Re: SetClassLong GCL_CURSOR on custom window [Re: aschol] #219466 19/03/10 05:57 PM
Joined: Oct 2003
Posts: 3,918
A
argv0 Offline
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Did you try to subclass the window like I suggested?


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Re: SetClassLong GCL_CURSOR on custom window [Re: argv0] #219473 19/03/10 10:33 PM
Joined: Jul 2004
Posts: 7
A
aschol Offline OP
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
A
Joined: Jul 2004
Posts: 7
Yea I did, but I found out Windows restores the class cursor EVERY time there's a WM_MOUSEMOVE message. I think my method is the only way I can stop the flickering. Do you have any other ideas?
Thanks

N.B: http://blogs.msdn.com/oldnewthing/archive/2006/02/27/539880.aspx has some more on it, but nobody there had a great solution either frown

Re: SetClassLong GCL_CURSOR on custom window [Re: aschol] #219474 20/03/10 12:11 AM
Joined: Oct 2003
Posts: 3,918
A
argv0 Offline
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
I'm not quite sure what the disadvantage of reassigning to another window class would be.. I don't think mIRC makes much use of the classes themselves.. I could be wrong.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Re: SetClassLong GCL_CURSOR on custom window [Re: argv0] #219494 20/03/10 11:48 AM
Joined: Jul 2004
Posts: 7
A
aschol Offline OP
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
A
Joined: Jul 2004
Posts: 7
I wasn't sure you could reassign the window's class after it had been created? I've been doing a bit more research and found out about "superclassing" - seems to be exactly what I need so i'll give that a shot.

EDIT: Ok it seems superclassing is just for creating new windows from an edited class, annoying

Last edited by aschol; 20/03/10 12:03 PM.