Last active
September 24, 2025 14:51
-
-
Save DavidBevi/72c90510e1ad769976633320ca2d1727 to your computer and use it in GitHub Desktop.
AHK v2, steal mouse-movement messages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; DEMO SCRIPT | |
| ; Hold down ENABLER_KEY to block-cursor and move-gui | |
| #Requires AutoHotkey v2.0+ | |
| #SingleInstance Force | |
| global ENABLER_KEY := "Home" ;<--- EDIT THIS LINE TO CHANGE ENABLER_KEY -------------------------- | |
| ; Other variables --------------------------------------------------------------------------------- | |
| global WH_MOUSE_LL := 14 | |
| global WM_MOUSEMOVE := 0x0200 | |
| global WM_USER := 0x0400 | |
| global CUSTOM_MOUSE_MSG := WM_USER + 123 | |
| global pCallback := 0 | |
| global hHook := 0 | |
| global targetHwnd := 0 | |
| ; Hotkeys ----------------------------------------------------------------------------------------- | |
| Esc::(A_ThisHotkey=A_PriorHotkey and A_TimeSincePriorHotkey<200)? Reload(): {} | |
| ^!Esc:: UninstallHook(), ExitApp() | |
| Hotkey(ENABLER_KEY,(*)=>{}) | |
| ; Main -------------------------------------------------------------------------------------------- | |
| ; | |
| ; Gui | |
| g:=Gui("+AlwaysOnTop +ToolWindow -Caption -DPIScale") | |
| g.SetFont("s10 bold") | |
| g.AddText(,"Hold " StrUpper(ENABLER_KEY) " and`nmove the mouse") | |
| g.Show() | |
| targetHwnd := g.Hwnd | |
| WinSetTransparent(188,targetHwnd) | |
| ; | |
| ; Hook (in hook thread) | |
| If !pCallback ; Create native callback. ParamCount = 3 (nCode, wParam, lParam) | |
| pCallback := CallbackCreate(LLMouseProc, "", 3) | |
| If !pCallback | |
| MsgBox("CallbackCreate failed.",,"RC")="Retry"? Reload(): ExitApp() | |
| if !hHook ; Install low-level mouse hook; pass hMod = 0 and threadId = 0 for global | |
| hHook := DllCall("SetWindowsHookEx", "Int",WH_MOUSE_LL, "Ptr",pCallback, "Ptr",0, "UInt",0, "Ptr") | |
| If !hHook { | |
| try CallbackFree(pCallback) | |
| MsgBox("SetWindowsHookEx failed. Try running elevated.",,"RC")="Retry"? Reload(): ExitApp() | |
| } | |
| ; | |
| OnExit(UninstallHook) | |
| ; | |
| ; Message handler (in main thread) | |
| OnMessage(CUSTOM_MOUSE_MSG, HandleFilteredMouseEvents) | |
| ; Functions --------------------------------------------------------------------------------------- | |
| UninstallHook(*) { | |
| global pCallback, hHook | |
| hHook? DllCall("UnhookWindowsHookEx", "Ptr", hHook) :{} | |
| pCallback? CallbackFree(pCallback) :{} | |
| } | |
| ; Low-level mouse callback manager (in hook thread) | |
| LLMouseProc(nCode, wParam, lParam) { | |
| global ENABLER_KEY, targetHwnd | |
| static ox:=0, oy:=0 | |
| if !GetKeyState(ENABLER_KEY, "P") { | |
| ; Calculate origin (ox, oy) | |
| ox := NumGet(lParam+0,0,"Int") | |
| oy := NumGet(lParam+0,4,"Int") | |
| } else if (!nCode && wParam=0x0200 && targetHwnd) { | |
| ; Calculate delta (dx, dy) | |
| dx := ox- NumGet(lParam+0,0,"Int") | |
| dy := oy- NumGet(lParam+0,4,"Int") | |
| ; Fwd delta (dx, dy), return non-zero to block cursor | |
| DllCall("PostMessage", "Ptr",targetHwnd, "UInt",CUSTOM_MOUSE_MSG, "Ptr",dx, "Ptr",dy) | |
| return(1) | |
| } | |
| ; Fwd to next hook | |
| return DllCall("CallNextHookEx", "Ptr",0, "Int",nCode, "Ptr",wParam, "Ptr",lParam, "Ptr") | |
| } | |
| ; Filtered mouse-events manager (in main thread) - safe to call GUI functions here | |
| HandleFilteredMouseEvents(dx, dy, msg, hwnd) { | |
| g.GetPos(&gx, &gy) | |
| MoveGUI(targetHWND, gx+dx, gy+dy) | |
| } | |
| ; Move GUI without activating it - with flags SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE= 0x0001|0x0004|0x0010= 0x0015 | |
| MoveGUI(hwnd,x,y)=> DllCall("SetWindowPos", "Ptr",hwnd, "Ptr",0, "Int",x, "Int",y, "Int",0, "Int",0, "UInt",0x0015) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment