0

I am using a global mouse event handler that was originally posted here.

The code posted in the original question works perfectly except that for some reason when I am using it, it is only triggered exactly once. (After that, it never gets triggered again.)

// Subscribe to Event, (placed this in constructor)
MouseHook.Start();  
MouseHook.MouseAction += new EventHandler(Event);

// ...

// This function only gets triggered once
private void Event(object sender, EventArgs e)
{
   // Do something
}

But, through some experimentation, I did get it working so that it does get triggered with each mouse click now (not just the first one).

I changed the function from this:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
    {
       MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));  
       MouseAction(null,new EventArgs());
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

To this:

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
    {
       MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));  
       MouseAction(null,new EventArgs());

       // Added these two lines, works perfectly now
       stop();
       Start();
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}

But I have no idea why 1) I needed to add these extra lines for my code, and 2) no one else seems to be having this problem.

Can someone explain:

  1. Why am I experiencing this issue in the first place, and
  2. Is my "workaround" shown above valid?
ImaginaryHuman072889
  • 4,953
  • 7
  • 19
  • 51
  • 2
    The standard reason is trying to debug the hook callback function. Windows imposes a timeout on the callback to prevent a hook from making the machine unusable, if it takes longer than 5 seconds then it unceremoniously uninstalls the hook without telling you about it. That timeout will always strike when you set a breakpoint. Google "LowLevelHooksTimeout" to find out how to change it. – Hans Passant Sep 23 '18 at 08:32
  • @HansPassant Ah! That explains it then. My `Event` function checks how often it was since the last mouse click occurred and if a certain time is exceeded, it displays an HMI login window where users must enter their credentials. This almost always would take more than 5 seconds for users to enter. Instead of increasing the timeout (because there is no known upper limit), is my solution above valid using the `Start` and `stop`? – ImaginaryHuman072889 Sep 23 '18 at 11:21
  • That will do it. Hanging the hook callback is very ugh, hard to predict the side-effects. Just use a timer, stop and restart it in the callback, when it ticks display the dialog. – Hans Passant Sep 23 '18 at 12:07
  • @HansPassant Thanks. I am also wondering if it would be better to `stop` before the login window is even displayed and then `Start` again after it closes, instead of allowing the timeout to occur and then restarting it. Do you agree? – ImaginaryHuman072889 Sep 23 '18 at 13:10

0 Answers0