- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When a user takes the mouse cursor into a region of the screen defined by cx1,cy1,cx2,cy2 I am successfully getting the cursor to change to something other than the default. When it moves out of this region it changes back to the default. I'm using:
case(WM_SETCURSOR)
if(xpos<=cx1.or.xpos>=cx2.or.ypos<=cy1.or.ypos>-cy2)then
iret = SetCursor(hcursor_default)
else
iret = SetCursor(hcursor)
end if
This works fine until the cursor is moved quickly over the toolbar. There's no problem if I move it nice and slowly, but move it quickly and it will not change.
Please can someone suggest what's going on here?
With many thanks in advance,
Mike
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
WM_SETCURSOR is the brother of WM_MOUSEMOVE (I'm not sure exactly where it's generated, but they should arrive one after another instantly). The explanation, thus, appears to be that you don't get WM_MOUSEMOVE when the mouse leaves your window quickly.
Now, how to solve it depends on your window parent/child hierarchy... let's see...
The DefWindowProc function passes the WM_SETCURSOR message to a parent window before processing. If the parent window returns TRUE, further processing is halted. Passing the message to a window's parent window gives the parent window control over the cursor's setting in a child window. The DefWindowProc function also uses this message to set the cursor to an arrow if it is not in the client area, or to the registered class cursor if it is in the client area.
Does it explain the behaviour?
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
WM_SETCURSOR is the brother of WM_MOUSEMOVE (I'm not sure exactly where it's generated, but they should arrive one after another instantly). The explanation, thus, appears to be that you don't get WM_MOUSEMOVE when the mouse leaves your window quickly.
Now, how to solve it depends on your window parent/child hierarchy... let's see...
The DefWindowProc function passes the WM_SETCURSOR message to a parent window before processing. If the parent window returns TRUE, further processing is halted. Passing the message to a window's parent window gives the parent window control over the cursor's setting in a child window. The DefWindowProc function also uses this message to set the cursor to an arrow if it is not in the client area, or to the registered class cursor if it is in the client area.
Does it explain the behaviour?
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Jugoslav. It kind of helps to explain what's going on, but I don't really know what to do about it. Do I have to set up a message processing loop for the child window (the toolbar)? I haven't a clue how to do that if that's the case. Please, if possible, could you outline the steps I need to take?
With many thanks
Mike
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But, are your window and the toolbar a parent and a child or siblings?
If they're parent and child, you're supposed (at least, according to docs I quoted above, and a quick test confirms that's the case)to get WM_SETCURSOR message in the parent even when the mouse is over the toolbar.
If they're siblings, you can probably solve the problem by moving WM_SETCURSOR processing to the window procedure of their common parent. (You can hit-test the mouse position usingwParam -> MapWindowPoints).
Yet, I can't fully explain the effect you're observing. There's a lot of ping-pong involved with passing the message around... Can you check with Spy++ what is going on with WM_SETCURSOR for the toolbar & parent (note: wParam is handle of the window containing the mouse, which is in general not identical with hWnd -- wParam can be hWnd's child).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Jugoslav,
Yes, the toolbar is a child of the main window.
It seems to be the WM_MOUSEMOVE message that's not being processed in the main window when the cursor is over the toolbar. This means that if it moved there even moderately quickly, the most recent x & y positions are frozen,placing the cursorinside the graphical area as far as WM_SETCURSOR is concerned, even though it is really outside.
Any suggestions?
With many thanks
Mike
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...but you should test WM_SETCURSOR rather than WM_MOUSEMOVE. Although they're brethren, the difference is that WM_MOUSEMOVE doesn't do a "ping-pong" from children to parent. In other words, when WM_MOUSEMOVE arrives in the toolbar, WM_SETCURSOR will follow it immediately, but WM_SETCURSOR will be then sent to the parent, while WM_MOUSEMOVE will not.
Where do your "xpos" and "ypos" come from? GetCursorPos?
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thankyou Jugoslav, problem solved.
I was getting xpos & ypos thus:
case (WM_MOUSEMOVE)
xpos = LOWORD(lParam); ypos = HIWORD(lParam)
but by using GetCursorPos in case (WM_SETCURSOR) there's no problem.
Many thanks again.
regards
Mike
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...converted to client-coordinates via MapWindowPoints or ScreenToClient, I assume?
Glad to hear the problem is solved...
Jugoslav
(6 working hours to vacation :-) )

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page