tags:

views:

685

answers:

4

I'm trying to implement a custom control in C# and I need to get events when the mouse is hovered. I know there is the MouseHover event but it only fires once. To get it to fire again I need to take the mouse of the control and enter it again.

Is there any way I can accomplish this?

+2  A: 

Why not subscribe to the MouseMove events in the MouseHover event, then unsubscribe in the MouseLeave event

Edit:

One way to determine if the mouse is stopped would be to start a timer every time you get a mouse move event, when the timer has elapsed then you could consider the mouse stopped. The reason for removing the MouseMove events on MouseLeave would allow you to only receive events while the mouse is over your control.

benPearce
Can you clarify what you mean? I already handle the MouseMove event and it only tells me when the mouse is moving, not when it is stopped.
triton
Heh. Same idea. +1
lc
I had thought about using a timer. I'm gonna try that tomorrow. And I can't use the other option because I need to receive mouse events even when the mouse is outside the control.
triton
I am talking about the mouse move events for this control only, not the application. If the mouse move events cannot be turned on and off for the control, then you could calculate if the current mouse movement in within the bounds of the control.
benPearce
The problem is: this control is the application. It's an OpenGL control that occupies the entire area of the window.
triton
+3  A: 

Let's define "stops moving" as "remains within an x pixel radius for n ms".

Subscribe to the MouseMove event and use a timer (set to n ms) to set your timeout. Each time the mouse moves, check against the tolerance. If it's outside your tolerance, reset the timer and record a new origin.

Pseudocode:

Point lastPoint;
const float tolerance = 5.0;

//you might want to replace this with event subscribe/unsubscribe instead
bool listening = false;

void OnMouseOver()
{
    lastpoint = Mouse.Location;
    timer.Start();
    listening = true; //listen to MouseMove events
}

void OnMouseLeave()
{
    timer.Stop();
    listening = false; //stop listening
}

void OnMouseMove()
{
    if(listening)
    {
        if(Math.abs(Mouse.Location - lastPoint) > tolerance)
        {
            //mouse moved beyond tolerance - reset timer
            timer.Reset();
            lastPoint = Mouse.Location;
        }
    }
}

void timer_Tick(object sender, EventArgs e)
{
    //mouse "stopped moving"
}
lc
Thanks, I'll try that. :)
triton
I ended up doing something much simpler using a Timer. It's kind of "hackish" but it gets the job done. Thanks for the help.
triton
@lc: I have a similar implementation, but have not found it necessary to use a "tolerance". Just checking if last mouse location is different from the current one works fine.
Wim Coenen
A: 

I realize that this is an old topic but I wanted to share a way I found to do it: on the mouse move event call ResetMouseEventArgs() on the control that catches the event.

A: 

Thanx! ResetMouseEventArgs() was the solution.

CLS