I need a way to set the MouseHoverTime Property, or some other way of making it so that the mouse needs to be over a control for a given amount of time before an event kicks in.
I have a set of controls that need to execute code when the mouse passes onto them, which can be done with either MouseEnter or MouseHover. However, when the mouse passes quickly over many of these controls, the code event for each control gets run in full. This makes the running of the program painfully and impractically slow. If I could set a certain time threshold for the mouse to stay over the control, then the event would only be called when the mouse stays over the control, and not when it briefly passes over it.
Private Sub Tile_MouseHover(Sender As Object, e As EventArgs)
CODE
CODE
CODE
End Sub
The code does give the intended results. It just gives them at a snails pace, because every time the cursor so much as brushes a control, all of the code within it gets executed.
The goal results would be as follows:
When the cursor hovers over a control, it must remain there for 1-2 seconds before calling the event.
If the cursor leaves before this, the event doesn't get called at all.
I've posted the C# version of the answer here with a bit more details.
Note: The answer doesn't claim to solve the performance issue which
you shared in the question, but shows how you can increase the mouse
hover delay time.
The hover time has been set in NativeMethods.TRACKMOUSEEVENT
to 100 milliseconds.
You can handle WM_MOUSEMOVE
and call TrackMouseEvent
by setting desired timeout for mouse hover as dwHoverTime
field of the TRACKMOUSEEVENT
. Also handle WM_MOUSEHOVER
and raise a custom event like MyMouseHover
, then you can subscribe for MyMouseHover
event. You can find a similar approach in my post for handling hover event on title bar of a form: Handle Mouse Hover on Titlebar of Form.
VB.NET - Hover event with custom hover time
Her is an example of a control which raises MyMouseHover
event with 500 ms delay:
Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Public Class SampleControl
Inherits Control
<DllImport("user32.dll")>
Private Shared Function TrackMouseEvent(ByRef lpEventTrack As TRACK_MOUSE_EVENT) _
As Integer
End Function
<StructLayout(LayoutKind.Sequential)>
Private Structure TRACK_MOUSE_EVENT
Public cbSize As UInteger
Public dwFlags As UInteger
Public hwndTrack As IntPtr
Public dwHoverTime As UInteger
Public Shared ReadOnly Empty As TRACK_MOUSE_EVENT
End Structure
Private track As TRACK_MOUSE_EVENT = TRACK_MOUSE_EVENT.Empty
Const WM_MOUSEMOVE As Integer = &H200
Const WM_MOUSEHOVER As Integer = &H2A1
Const TME_HOVER As Integer = &H1
Const TME_LEAVE As Integer = &H2
Public Event MyMouseHover As EventHandler
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_MOUSEMOVE Then
track.hwndTrack = Me.Handle
track.cbSize = CUInt(Marshal.SizeOf(track))
track.dwFlags = TME_HOVER Or TME_LEAVE
track.dwHoverTime = 500
TrackMouseEvent(track)
End If
If m.Msg = WM_MOUSEHOVER Then
RaiseEvent MyMouseHover(Me, EventArgs.Empty)
End If
MyBase.WndProc(m)
End Sub
End Class