Jump to content

Recommended Posts

Posted

I just discovered this great tool! I also had some problems. This code will fix a few of them. Specifically: 

  1. This code tells apart physical input from the mouse, from simulated input from AutoIt
  2. This code fixes the problem with the order of releasing callbacks and hooks. 
  3. A problem I didn't see reported: I have a script that will take control from the user, activate a window and do a few clicks. But using the UDF as published (v1.8) there was a brief window of time, around each MouseMove() or MouseClick() uses, where I was able to move the mouse. And furthermore, if the mouse was moved too much then it got "out of the cage", and the block was lifted. 

The most important change is on __BlockInputEx_MouseHook_Proc() funcion, where

Local $MOUSEHOOKSTRUCT = DllStructCreate("ptr pt;hwnd hwnd;uint wHitTestCode;ulong_ptr dwExtraInfo", $lParam)
Local $iExtraInfo = DllStructGetData($MOUSEHOOKSTRUCT, "dwExtraInfo")

and later

If $iBlockAllInput = 0 And $iExtraInfo <> 0 Then

are changed to:

Local $MOUSEHOOKSTRUCT = DllStructCreate("long x;long y;dword mouseData;dword flags;dword time;ulong_ptr dwExtraInfo", $lParam)
Local $iFlags = DllStructGetData($MOUSEHOOKSTRUCT, "flags")

and

If $iBlockAllInput = 0 And BitAND($iFlags, 0x01) Then

This correctly separates physical from simulated mouse events. But only on separate threads, see below. 

 

The biggest change is on __BlockInputEx_UnhookWinHooks_Proc function, that is replaced: 

Func __BlockInputEx_UnhookWinHooks_Proc()
    Local $bKeyOK = True
    Local $bMouseOK = True
    Local $iError = 0
    Local $iWinError
    ; ----------------------------------------------------
    ; 1. Remove the keyboard hook
    ; ----------------------------------------------------
    If IsPtr($ah_MouseKeyboard_WinHooks[2]) Then
        If Not _WinAPI_UnhookWindowsHookEx($ah_MouseKeyboard_WinHooks[2]) Then
            $iWinError = _WinAPI_GetLastError()
            ; 1404 = Invalid hook handle
            ; 1431 = Hook not installed
            If $iWinError <> 1404 And $iWinError <> 1431 Then
                $bKeyOK = False
                $iError = $iWinError
            EndIf
        EndIf
        If $bKeyOK Then $ah_MouseKeyboard_WinHooks[2] = 0
    EndIf

    ; ----------------------------------------------------
    ; 2. Remove the mouse hook
    ; ----------------------------------------------------
    If IsPtr($ah_MouseKeyboard_WinHooks[3]) Then
        If Not _WinAPI_UnhookWindowsHookEx($ah_MouseKeyboard_WinHooks[3]) Then
            $iWinError = _WinAPI_GetLastError()
            If $iWinError <> 1404 And $iWinError <> 1431 Then
                $bMouseOK = False
                $iError = $iWinError
            EndIf
        EndIf
        If $bMouseOK Then $ah_MouseKeyboard_WinHooks[3] = 0
    EndIf

    ; ----------------------------------------------------
    ; 3. Free the keyboard callback
    ;    Only after its hook has been removed
    ; ----------------------------------------------------
    If $bKeyOK Then
        If $ah_MouseKeyboard_WinHooks[0] > 0 Then
            DllCallbackFree($ah_MouseKeyboard_WinHooks[0])
            $ah_MouseKeyboard_WinHooks[0] = 0
        EndIf
    EndIf

    ; ----------------------------------------------------
    ; 4. Free the mouse callback
    ;    Only after its hook has been removed
    ; ----------------------------------------------------
    If $bMouseOK Then
        If $ah_MouseKeyboard_WinHooks[1] > 0 Then
            DllCallbackFree($ah_MouseKeyboard_WinHooks[1])
            $ah_MouseKeyboard_WinHooks[1] = 0
        EndIf
    EndIf

    ; ----------------------------------------------------
    ; 5. Report success or failure
    ; ----------------------------------------------------
    If Not $bKeyOK Or Not $bMouseOK Then
        Return SetError(1, $iError, 0)
    EndIf

    Return 1
EndFunc

 

There is also an important consideration: To correctly block all events, the thread that locks the mouse cannot be the same which runs the main script, this is what caused the trouble with "getting out of the cage". You need to create a "helper script" which encapsulates the UDF, compile it, and run it from the main script. You will find all details on the attached file. Disclaimer: An AI was used to assist with the fix and to redact the attached report. 

BlockInputEx_Forum_Patch.zip

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...