0

I have a hook created with these lines (works properly, except for the new return 1 line). What I'm trying to do is disable the right click:

if (_keyboardHook == IntPtr.Zero && _mouseHook == IntPtr.Zero)
{
    IntPtr hInstance = LoadLibrary("User32");
    //IntPtr hInstance = Marshal.GetHINSTANCE(Assembly.GetCallingAssembly().GetModules()[0]);

    _keyProc = new HookProc(keyboardHookProc);
    _keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, _keyProc, hInstance, 0);

    try
    {
        _mouseProc = new HookProc(mouseHookProc);
        _mouseHook = SetWindowsHookEx(WH_MOUSE_LL, _mouseProc, hInstance, 0);

And this is my mouseProc:

private int mouseHookProc(int code, int wParam, IntPtr lParam)
{
    try
    {
        _lastHit = DateTime.Now;
        bool go = true;
        if (code >= 0)
        {
            MouseHookStruct mouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

            //only process if button down or mouse wheel.
            if (wParam == WM_LBUTTONDOWN
             || wParam == WM_MOUSEWHEEL
             || wParam == WM_MBUTTONDOWN
             || wParam == WM_XBUTTONUP
             || wParam == WM_RBUTTONUP)
            {
                bool isWheel = false;
                bool isWheelUp = false;

                int keyCode = 0;
                switch (wParam)
                {
                    case WM_LBUTTONDOWN:
                        keyCode = 1;
                        break;

                    case WM_RBUTTONUP:
                    {
                        keyCode = 2;
                        go = false;
                        break;
                    }
    
                    case WM_XBUTTONUP:
                        var hWord = ((uint)((IntPtr)mouseHookStruct.MouseData) >> 16);
                        if (hWord == 1)
                            keyCode = 5;
                        if (hWord == 2)
                            keyCode = 6;
                        break;

                    case WM_MBUTTONDOWN:
                        keyCode = 4;
                        break;

                    case WM_MOUSEWHEEL:
                        short mouseDelta = (short)((mouseHookStruct.MouseData >> 16) & 0xffff);
                        isWheel = true;
                        isWheelUp = mouseDelta == 120;
                        break;

                    default:
                        break;
                }
    
                OnKeyArgs kea = new OnKeyArgs(keyCode)
                {
                    IsCtrlPressed = IsPressed(VK_CTRL),
                    IsAltPressed = IsPressed(VK_ALT),
                    IsShiftPressed = IsPressed(VK_SHIFT),
                    WheelInfo = new MouseWheelInfo()
                };
    
                if (isWheel)
                {
                    kea.WheelInfo.IsWheelInvolved = true;
                    kea.WheelInfo.IsWheelUp = isWheelUp;
                }
    
                KeyDown?.Invoke(this, kea);
            }
        }
    
        if (go)
            return CallNextHookEx(_mouseHook, code, wParam, ref lParam);
        else
            return 1;
    }
    catch (Exception ex)
    {
        Logger.Error("Error no mouse hook proc", ex);
        return 0;
    }
}

I also have a running check to re-start the hook in case Windows shuts it down:

IntPtr hInstance = LoadLibrary("User32");

while (true)
{
    int milliseconds = MilisecondsElapsedFromNow(_lastHit);
    if (milliseconds > 6000 || milliseconds < 0)
    {
        Application.Current.Dispatcher.Invoke(() =>
        {
            UnhookWindowsHookEx(_mouseHook);
            _mouseHook = IntPtr.Zero;
            Thread.Sleep(100);
            _mouseHook = SetWindowsHookEx(WH_MOUSE_LL, _mouseProc, hInstance, 0);
            // Logger.Warning($"Mouse listening for hotkeys restored, Ptr: {_mouseHook}");
        });
    }
    
    Thread.Sleep(500);
}

It works fine, but after a few right clicks, the whole mouse stops working on the PC (if I remove the return 1 line, there are no problems!).

PS: the mouse stops working even after I stop the debugging/execution of my program!

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • @500-InternalServerError Returning a non-zero value is the correct way to block input in a `WH_MOUSE_LL` hook, per the [documentation](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644986(v=vs.85)). – Remy Lebeau May 17 '21 at 18:06
  • @MatíasMacotinsky what does your `MouseHookStruct` look like? A `WH_MOUSE_LL` hook receives a [`MSLLHOOKSTRUCT`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msllhookstruct), not a [`MOUSEHOOKSTRUCT`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mousehookstruct). The latter is used with a `W_MOUSE` hook instead. – Remy Lebeau May 17 '21 at 18:10
  • It is indeed a MSLLHOOKSTRUCT. – Matías Macotinsky May 17 '21 at 18:56
  • Instead of using a timer loop, consider unhooking and re-hooking after each hook intercept. – birdwes May 17 '21 at 22:59
  • I created a sample but did not reproduce the problem, maybe you can reduce the code and show [a minimal, reproducible sample](https://stackoverflow.com/help/minimal-reproducible-example) to help us determine the problem . – Zeus May 18 '21 at 03:16
  • @birdwes I dont quite understand how that would solve windows unhooking my code – Matías Macotinsky May 19 '21 at 04:47
  • @SongZhu-MSFT Have you tried to click a few times? the code i posted works for me but after a while the click stops workng, doesnt seem to be instant – Matías Macotinsky May 19 '21 at 04:48
  • Yes, I tried multiple clicks and it always works fine. – Zeus May 19 '21 at 05:10
  • @MatíasMacotinsky Windows has a hook timer. Re-hooking at the end of each intercept will prevent the timer from removing your hook. See https://social.msdn.microsoft.com/Forums/Windowsapps/en-US/f6032ca1-31b8-4ad5-be39-f78dd29952da/hooking-problem-in-windows-7?forum=windowscompatibility – birdwes May 19 '21 at 10:08

0 Answers0