Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

mouse cursor control

michael_green
Beginner
1,359 Views
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
0 Kudos
8 Replies
Jugoslav_Dujic
Valued Contributor II
1,359 Views
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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,359 Views
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
0 Kudos
michael_green
Beginner
1,359 Views
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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,359 Views
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
0 Kudos
michael_green
Beginner
1,359 Views
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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,359 Views
...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
0 Kudos
michael_green
Beginner
1,359 Views
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
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,359 Views
...converted to client-coordinates via MapWindowPoints or ScreenToClient, I assume?
Glad to hear the problem is solved...
Jugoslav
(6 working hours to vacation :-) )
0 Kudos
Reply