Figure out when mouse cursor enters/leaves form

C

cb.brite

Hello,

I have tried this using the MouseEnter/MouseLeave events. However these
events do not really refer to the rectangular shape of the form, but
the client area (form area minus children areas). This means that if
the mouse is currently inside the form's client area and it enters a
child, a MouseLeave event will be generated on the form.

One little trick to overcome this is to do a point-in-rectangle test
inside the MouseLeave handler:

if (!Bounds.Contains(MousePosition))
{
// mouse really left the form
}


This however doesn't always work, for example if you have another
window on top of yours, because that window's area will be treated just
like a child area.

Anyone knows how to do this cleanly?

Thanks in advance,
Cosmin.
 
M

Martin Z

Hello,

I have tried this using the MouseEnter/MouseLeave events. However these
events do not really refer to the rectangular shape of the form, but
the client area (form area minus children areas). This means that if
the mouse is currently inside the form's client area and it enters a
child, a MouseLeave event will be generated on the form.

One little trick to overcome this is to do a point-in-rectangle test
inside the MouseLeave handler:

if (!Bounds.Contains(MousePosition))
{
// mouse really left the form
}


This however doesn't always work, for example if you have another
window on top of yours, because that window's area will be treated just
like a child area.

Anyone knows how to do this cleanly?

Thanks in advance,
Cosmin.

You could iterate through the control tree and add MouseEnter and
MouseLeave events to every single control. Then do the same for every
single ControlAdded and ControlRemoved, adding/removing all four event
bindings to every new control added anywhere in the tree. Just recurse
through the control.Controls collection.

Thus, you know which control the mouse is pointing at at any given
time.... the only worry is that I don't know what order things happen
in - when a mouse transitions from one control to the next, if it
"Leaves" control X before it "enters" control Y, there will be a
momentary "gap" where your app thinks it isn't pointing at the form.

If "Leave" happens first, then I guess you just use a hack with a
timer. The timer runs as fast as is reasonable for good UI feedback -
when, in two sequential cycles, the mouse is outside of all controls,
then you accept that it has left the form. If it ever inside of the
set of all controls, then it is still inside the form. Hacky, but it
should work.
 
C

cb.brite

Seems a bit overkill just just for this... :|

Martin said:
You could iterate through the control tree and add MouseEnter and
MouseLeave events to every single control. Then do the same for every
single ControlAdded and ControlRemoved, adding/removing all four event
bindings to every new control added anywhere in the tree. Just recurse
through the control.Controls collection.

Thus, you know which control the mouse is pointing at at any given
time.... the only worry is that I don't know what order things happen
in - when a mouse transitions from one control to the next, if it
"Leaves" control X before it "enters" control Y, there will be a
momentary "gap" where your app thinks it isn't pointing at the form.

If "Leave" happens first, then I guess you just use a hack with a
timer. The timer runs as fast as is reasonable for good UI feedback -
when, in two sequential cycles, the mouse is outside of all controls,
then you accept that it has left the form. If it ever inside of the
set of all controls, then it is still inside the form. Hacky, but it
should work.
 
M

Martin Z

Why? It might prove to be a performance killer - testing will show
that. But semantically, it's simple. Code one event-binding function
that sets up the events and applies itself to all children - then make
the reverse. This pair is what is called by the ControlAdded and
ControlRemoved handlers. Then you just have the MouseEnter write to a
shared "CurrentMouseControl" member - and the MouseLeave checks to make
sure that it's not leaving the "CurrentMouseControl" member (assuming
the MouseLeave-after-MouseEnter behaviour that I'm hoping for).

The complex, wasteful, overkill solution is only needed in the case
that Leave happens first.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top