Inverting Mouse movement

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Manex
Posts: 5
Joined: 27 Jan 2023, 07:06

Inverting Mouse movement

Post by Manex » 27 Jan 2023, 07:14

I am trying to invert my mouse movement I searched for the code on the internet and I found this:

Code: Select all

;By Raccoon Dec-2010
;Mouse Inverse using Mouse Hook

#SingleInstance, Force  ; Only one at a time.
#NoEnv         ; Just use it.
#Persistent    ; Needed if there are no hotkeys or timers.
OnExit, OnExit ; Needed to Unhook when Exiting.

hHookMouse := SetWindowsHookEx(14, RegisterCallback("WH_MOUSE_LL", "Fast"))

return ; End Auto-execute.

OnExit:
  UnhookWindowsHookEx(hHookMouse) ; VERY IMPORTANT.
  ExitApp

WH_MOUSE_LL(nCode, wParam, lParam)
{
  Static lx:=999999, ly
  Critical
  
  if !nCode && (wParam = 0x200) { ; WM_MOUSEMOVE 

    mx := NumGet(lParam+0, 0, "Int") ; x-coord
    my := NumGet(lParam+0, 4, "Int") ; y-coord
    ;OutputDebug % "MouseMove : mx = " mx ", lx = " lx ", my = " my ", ly = " ly
    
    if (lx != 999999) { ; skip if last-xy coordinates haven't been initilized (first move).

      ; normal movement example.
      ;mx := lx + (mx - lx)
      ;my := ly + (my - ly)
      
      ; modify (invert) movement.
      mx := lx - (mx - lx)
      my := ly - (my - ly)
      
      ; modify (half-speed) movement.
      ;mx := lx + (mx - lx) / 2
      ;my := ly + (my - ly) / 2
      
      ; control desktop edges  /// this method is replaced by MouseGetPos or GetCursorPos below.
      ;if (mx < 0)
      ;  mx := 0
      ;else if (mx >= A_ScreenWidth)
      ;  mx := A_ScreenWidth -1
      ;if (my < 0)
      ;  my := 0
      ;else if (my >= A_ScreenHeight)
      ;  my := A_ScreenHeight -1
    }
    
    ; This is where the magic happens, in combination with Return 1.
    DllCall("SetCursorPos", "Int", mx, "Int", my)

    ;CoordMode, Mouse, Screen ; only needed if using MouseGetPos,
    ;MouseGetPos, lx, ly      ; lets use GetCursorPos instead.
    VarSetCapacity(lpPoint,8)
    DllCall("GetCursorPos", "Uint", &lpPoint) ; SetCursorPos controls desktop edges; less math for us.
    lx := NumGet(lpPoint, 0, "Int")
    ly := NumGet(lpPoint, 4, "Int")
    
    ; Send the modified mouse coords to other hooking processes along the chain.
    NumPut(mx, lParam+0, 0, "Int")
    NumPut(my, lParam+0, 4, "Int")
    ret:=DllCall("CallNextHookEx", "Uint", 0, "int", nCode, "Uint", wParam, "Uint", lParam)
    ;Return ret
    
    return 1 ; Halt default mouse processing. (same method used by 'BlockInput, MouseMove')
  }
  else {
    return DllCall("CallNextHookEx", "Uint", 0, "int", nCode, "Uint", wParam, "Uint", lParam) 
  }
} ; End WH_MOUSE_LL

SetWindowsHookEx(idHook, pfn)
{
  return DllCall("SetWindowsHookEx", "int", idHook, "Uint", pfn, "Uint", DllCall("GetModuleHandle", "Uint", 0), "Uint", 0)
}

UnhookWindowsHookEx(hHook)
{
  return DllCall("UnhookWindowsHookEx", "Uint", hHook)
}

; Since the below function is called so frequently, it's faster to use the DllCall() instead of this func.
CallNextHookEx(nCode, wParam, lParam, hHook = 0)
{
  return DllCall("CallNextHookEx", "Uint", hHook, "int", nCode, "Uint", wParam, "Uint", lParam)
}]
It is an old script (2010) but it seems to be very well coded (all credits to the author), but I don't know why I cannot make it work, help me please why is not working?

Manex
Posts: 5
Joined: 27 Jan 2023, 07:06

Re: Inverting Mouse movement

Post by Manex » 27 Jan 2023, 09:02

Okay so after touching things here and there I found why is not working, it's because it's for 32bit system I compiled the script into 32bit executable and it works, but now my question is how can I make it for 64bit system?

Rohwedder
Posts: 7611
Joined: 04 Jun 2014, 08:33
Location: Germany

Re: Inverting Mouse movement

Post by Rohwedder » 27 Jan 2023, 09:23

Hallo,
only a try:

Code: Select all

;By Raccoon Dec-2010
;Mouse Inverse using Mouse Hook
#SingleInstance, Force  ; Only one at a time.
#NoEnv         ; Just use it.
#Persistent    ; Needed if there are no hotkeys or timers.
OnExit, OnExit ; Needed to Unhook when Exiting.
hHookMouse := DllCall("SetWindowsHookEx"
, "Int", 14
, "Ptr", RegisterCallback("WH_MOUSE_LL")
, "Ptr", DllCall("GetModuleHandle", "Ptr", 0, "Ptr")
, "UInt", 0)
RETURN ; End Auto-execute.
OnExit:
UnhookWindowsHookEx(hHookMouse) ; VERY IMPORTANT.
ExitApp
WH_MOUSE_LL(nCode, wParam, lParam)
{
	Static lx:=999999, ly
	Critical
	if !nCode && (wParam = 0x200)
	{ ; WM_WH_MOUSE_LL
		mx := NumGet(lParam+0, 0, "Int") ; x-coord
		my := NumGet(lParam+0, 4, "Int") ; y-coord
		;OutputDebug % "WH_MOUSE_LL : mx = " mx ", lx = " lx ", my = " my ", ly = " ly
		if (lx != 999999)
		{ ; skip if last-xy coordinates haven't been initilized (first move).
			; normal movement example.
			;mx := lx + (mx - lx)
			;my := ly + (my - ly)
			; modify (invert) movement.
			mx := lx - (mx - lx)
			my := ly - (my - ly)
			; modify (half-speed) movement.
			;mx := lx + (mx - lx) / 2
			;my := ly + (my - ly) / 2
			; control desktop edges  /// this method is replaced by MouseGetPos or GetCursorPos below.
			;if (mx < 0)
			;  mx := 0
			;else if (mx >= A_ScreenWidth)
			;  mx := A_ScreenWidth -1
			;if (my < 0)
			;  my := 0
			;else if (my >= A_ScreenHeight)
			;  my := A_ScreenHeight -1
		}
		; This is where the magic happens, in combination with Return 1.
		DllCall("SetCursorPos", "Int", mx, "Int", my)
		;CoordMode, Mouse, Screen ; only needed if using MouseGetPos,
		;MouseGetPos, lx, ly      ; lets use GetCursorPos instead.
		VarSetCapacity(lpPoint,8)
		DllCall("GetCursorPos", "Uint", &lpPoint) ; SetCursorPos controls desktop edges; less math for us.
		lx := NumGet(lpPoint, 0, "Int")
		ly := NumGet(lpPoint, 4, "Int")
		; Send the modified mouse coords to other hooking processes along the chain.
		NumPut(mx, lParam+0, 0, "Int")
		NumPut(my, lParam+0, 4, "Int")
		ret:=DllCall("CallNextHookEx", "Uint", 0, "int", nCode, "Uint", wParam, "Uint", lParam)
		;Return ret
		Return 1 ; Halt default mouse processing. (same method used by 'BlockInput, WH_MOUSE_LL')
	}
	else
		Return DllCall("CallNextHookEx", "Uint", 0, "int", nCode, "Uint", wParam, "Uint", lParam)
} ; End WH_MOUSE_LL
SetWindowsHookEx(idHook, pfn)
{
	Return DllCall("SetWindowsHookEx", "int", idHook, "Uint", pfn, "Uint", DllCall("GetModuleHandle", "Uint", 0), "Uint", 0)
}
UnhookWindowsHookEx(hHook)
{
	Return DllCall("UnhookWindowsHookEx", "Uint", hHook)
}
; Since the below function is called so frequently, it's faster to use the DllCall() instead of this func.
CallNextHookEx(nCode, wParam, lParam, hHook = 0)
{
	Return DllCall("CallNextHookEx", "Uint", hHook, "int", nCode, "Uint", wParam, "Uint", lParam)
}
I have only compared older and newer HookMouse scripts and unfortunately have too little idea about it.

Manex
Posts: 5
Joined: 27 Jan 2023, 07:06

Re: Inverting Mouse movement

Post by Manex » 27 Jan 2023, 12:43

Rohwedder wrote:
27 Jan 2023, 09:23
Hallo,
only a try:

Code: Select all

;By Raccoon Dec-2010
;Mouse Inverse using Mouse Hook
#SingleInstance, Force  ; Only one at a time.
#NoEnv         ; Just use it.
#Persistent    ; Needed if there are no hotkeys or timers.
OnExit, OnExit ; Needed to Unhook when Exiting.
hHookMouse := DllCall("SetWindowsHookEx"
, "Int", 14
, "Ptr", RegisterCallback("WH_MOUSE_LL")
, "Ptr", DllCall("GetModuleHandle", "Ptr", 0, "Ptr")
, "UInt", 0)
RETURN ; End Auto-execute.
OnExit:
UnhookWindowsHookEx(hHookMouse) ; VERY IMPORTANT.
ExitApp
WH_MOUSE_LL(nCode, wParam, lParam)
{
	Static lx:=999999, ly
	Critical
	if !nCode && (wParam = 0x200)
	{ ; WM_WH_MOUSE_LL
		mx := NumGet(lParam+0, 0, "Int") ; x-coord
		my := NumGet(lParam+0, 4, "Int") ; y-coord
		;OutputDebug % "WH_MOUSE_LL : mx = " mx ", lx = " lx ", my = " my ", ly = " ly
		if (lx != 999999)
		{ ; skip if last-xy coordinates haven't been initilized (first move).
			; normal movement example.
			;mx := lx + (mx - lx)
			;my := ly + (my - ly)
			; modify (invert) movement.
			mx := lx - (mx - lx)
			my := ly - (my - ly)
			; modify (half-speed) movement.
			;mx := lx + (mx - lx) / 2
			;my := ly + (my - ly) / 2
			; control desktop edges  /// this method is replaced by MouseGetPos or GetCursorPos below.
			;if (mx < 0)
			;  mx := 0
			;else if (mx >= A_ScreenWidth)
			;  mx := A_ScreenWidth -1
			;if (my < 0)
			;  my := 0
			;else if (my >= A_ScreenHeight)
			;  my := A_ScreenHeight -1
		}
		; This is where the magic happens, in combination with Return 1.
		DllCall("SetCursorPos", "Int", mx, "Int", my)
		;CoordMode, Mouse, Screen ; only needed if using MouseGetPos,
		;MouseGetPos, lx, ly      ; lets use GetCursorPos instead.
		VarSetCapacity(lpPoint,8)
		DllCall("GetCursorPos", "Uint", &lpPoint) ; SetCursorPos controls desktop edges; less math for us.
		lx := NumGet(lpPoint, 0, "Int")
		ly := NumGet(lpPoint, 4, "Int")
		; Send the modified mouse coords to other hooking processes along the chain.
		NumPut(mx, lParam+0, 0, "Int")
		NumPut(my, lParam+0, 4, "Int")
		ret:=DllCall("CallNextHookEx", "Uint", 0, "int", nCode, "Uint", wParam, "Uint", lParam)
		;Return ret
		Return 1 ; Halt default mouse processing. (same method used by 'BlockInput, WH_MOUSE_LL')
	}
	else
		Return DllCall("CallNextHookEx", "Uint", 0, "int", nCode, "Uint", wParam, "Uint", lParam)
} ; End WH_MOUSE_LL
SetWindowsHookEx(idHook, pfn)
{
	Return DllCall("SetWindowsHookEx", "int", idHook, "Uint", pfn, "Uint", DllCall("GetModuleHandle", "Uint", 0), "Uint", 0)
}
UnhookWindowsHookEx(hHook)
{
	Return DllCall("UnhookWindowsHookEx", "Uint", hHook)
}
; Since the below function is called so frequently, it's faster to use the DllCall() instead of this func.
CallNextHookEx(nCode, wParam, lParam, hHook = 0)
{
	Return DllCall("CallNextHookEx", "Uint", hHook, "int", nCode, "Uint", wParam, "Uint", lParam)
}
I have only compared older and newer HookMouse scripts and unfortunately have too little idea about it.
Thank you very much buddy it actually works! Now it's running on 64bit executable (which is waay more convinient) thanks!

Post Reply

Return to “Ask for Help (v1)”