0

I have an Excel form in which I use controls' mouse move event for simulating hovering effect. There's no problem when the form is showed modal.

When I show the form modeless, even with the stationary mouse, the mousemove event of every control is continuously fired (if the mouse is over that control). The CPU usage grows up to 26-30%.

Nothing changes if the mouse move event has no code inside. If I comment the entire events this strange behavior disappears.

It seems that the mere existence of the mouseMove event it's enough to create the problem.

I've searched a lot, but it seems I'm the only one having this problem. I can share the workbook if anyone wants to see it.

  • When you comment the handlers out, do you still see the messages with Spy++? – GSerg Feb 05 '20 at 18:47
  • @GSerg I'm trying to give a reasonable answer, but using Spy++ I cannot see any message at all.. But I never used it before.. Let me try to figure out how it works.. –  Feb 05 '20 at 19:30
  • @GSerg so I was using 32 in 64 app... However: when the control has the event handler there's a lot of WM_NCHITTEST and WM_MOUSEMOVE even with a stationary mouse. The same happens when the event is commented out BUT, in this case, the messages stop when the mouse is stationary. –  Feb 05 '20 at 19:58
  • Do you want the mousemove event to continously fire as long as the mouse is moving over the control or would it be enough if it fires once every time the mouse goes from "not over the control" to "over the control"? – GWD Feb 05 '20 at 20:11
  • @GWD I would prefer to have the event continuously fired while the mouse is moving, but if you have a solution with the second option it'll surely be an improvement... –  Feb 05 '20 at 20:18
  • Let me know if the solution using `sleep`, as described in my answer, helps, otherwise I have another idea. – GWD Feb 05 '20 at 20:50

1 Answers1

0

I have a relatively simple solution that should handle the CPU usage problem, this doesn't do anything against the event triggering while the mouse is stationary though. The idea is to use the sleep function provided by the windows API to decrease the frequency of the events activation.

So first you need to get the function:

#If VBA7 Then
    Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
    Public Declare Sub Sleep Lib "kernel32" (ByVal lngMilliSeconds As Long)
#End If

and then inside your userform:

Private Sub Label1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    sleep 1  '1 should be the time in milliseconds that the code will wait, 
             'in practice it waits 15ms (see edit below)
    'insert the rest of your code here
End Sub

The sleep 1 will make the code wait for one millisecond before resuming execution. Edit: in practice it will make the code wait for 15 milliseconds, see @GSergs comment to this answer.

This is usually enough to get rid of the cpu usage problem. If you don't need the event to trigger 65 times a second you can change the triggering frequency by waiting longer, for example with sleep 30.

If you only need the event to activate once every time the mouse goes from "not over the control" to "over the control" a solution is to use an activation flag:

Inside the Userforms Module:

Dim ControlActive As Boolean

Private Sub Label1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If Not ControlActive Then
        ControlActive = True
        'insert the rest of your code here
    End If
End Sub

Private Sub Userform_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If ControlActive Then
        ControlActive = False
    End If
End Sub
GWD
  • 3,081
  • 14
  • 30
  • `Sleep 1` is [`Sleep 15`](https://stackoverflow.com/q/9518106/11683). Also the right thing is `#If VBA7 Then` instead of `#If Win64 Then` and `#Else` instead of `#ElseIf Win32 Then`. – GSerg Feb 05 '20 at 21:00
  • @GSerg thank you for the information about Seep 15, this is new for me! Also yes #If VBA7 is of course correct, I updated my answer accordingly. – GWD Feb 05 '20 at 22:05