如何在Autohotkey中捕获和发送原始鼠标输入?

如何在Autohotkey中捕获和发送原始鼠标输入?,autohotkey,Autohotkey,我知道如何捕捉相对于屏幕的鼠标移动,但是在游戏中,鼠标移动是独立于鼠标在屏幕上的位置使用的,那又如何呢 例如,在游戏中,你的光标是隐藏的,但你可以无限地向左移动鼠标,然后转一圈,远远超过你的鼠标在屏幕上移动的空间。游戏可能会将你的隐形鼠标锁定在中间,或者让它移动直到它碰到窗口边缘,但在这一点上,任何记录鼠标相对于屏幕移动的尝试都是无用的 因此,如何捕获/发送原始鼠标输入。例如,如果我想通过鼠标输入告诉玩家向左转1000度,并记录玩家向左转1000度时的鼠标输入,我如何同时执行这两项操作 我的目标

我知道如何捕捉相对于屏幕的鼠标移动,但是在游戏中,鼠标移动是独立于鼠标在屏幕上的位置使用的,那又如何呢

例如,在游戏中,你的光标是隐藏的,但你可以无限地向左移动鼠标,然后转一圈,远远超过你的鼠标在屏幕上移动的空间。游戏可能会将你的隐形鼠标锁定在中间,或者让它移动直到它碰到窗口边缘,但在这一点上,任何记录鼠标相对于屏幕移动的尝试都是无用的

因此,如何捕获/发送原始鼠标输入。例如,如果我想通过鼠标输入告诉玩家向左转1000度,并记录玩家向左转1000度时的鼠标输入,我如何同时执行这两项操作


我的目标是最终记录玩家的各种控制,包括鼠标输入,以创建一个记录和回放用户输入的系统。我搜索了所有的ahk文档和谷歌,没有发现任何关于捕获和发送原始鼠标输入的信息

这已经由AHK论坛上一位名为evic的优秀用户为您解决了

它被调用并跟踪原始鼠标输入中的更改

我已经发布了他的鼠标增量脚本的几个不同变体之一。确保您按照上面的链接查看他所做的所有不同的操作

再说一遍,这不是我的工作

; Instantiate this class and pass it a func name or a Function Object
; The specified function will be called with the delta move for the X and Y axes
; Normally, there is no windows message "mouse stopped", so one is simulated.
; After 10ms of no mouse movement, the callback is called with 0 for X and Y
Class MouseDelta {
    State := 0
    __New(callback){
        ;~ this.TimeoutFn := this.TimeoutFunc.Bind(this)
        this.MouseMovedFn := this.MouseMoved.Bind(this)

        this.Callback := callback
    }

    Start(){
        static DevSize := 8 + A_PtrSize, RIDEV_INPUTSINK := 0x00000100
        ; Register mouse for WM_INPUT messages.
        VarSetCapacity(RAWINPUTDEVICE, DevSize)
        NumPut(1, RAWINPUTDEVICE, 0, "UShort")
        NumPut(2, RAWINPUTDEVICE, 2, "UShort")
        NumPut(RIDEV_INPUTSINK, RAWINPUTDEVICE, 4, "Uint")
        ; WM_INPUT needs a hwnd to route to, so get the hwnd of the AHK Gui.
        ; It doesn't matter if the GUI is showing, it still exists
        Gui +hwndhwnd
        NumPut(hwnd, RAWINPUTDEVICE, 8, "Uint")

        this.RAWINPUTDEVICE := RAWINPUTDEVICE
        DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
        OnMessage(0x00FF, this.MouseMovedFn)
        this.State := 1
        return this ; allow chaining
    }

    Stop(){
        static RIDEV_REMOVE := 0x00000001
        static DevSize := 8 + A_PtrSize
        OnMessage(0x00FF, this.MouseMovedFn, 0)
        RAWINPUTDEVICE := this.RAWINPUTDEVICE
        NumPut(RIDEV_REMOVE, RAWINPUTDEVICE, 4, "Uint")
        DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
        this.State := 0
        return this ; allow chaining
    }

    SetState(state){
        if (state && !this.State)
            this.Start()
        else if (!state && this.State)
            this.Stop()
        return this ; allow chaining
    }

    Delete(){
        this.Stop()
        ;~ this.TimeoutFn := ""
        this.MouseMovedFn := ""
    }

    ; Called when the mouse moved.
    ; Messages tend to contain small (+/- 1) movements, and happen frequently (~20ms)
    MouseMoved(wParam, lParam){
        Critical
        ; RawInput statics
        static DeviceSize := 2 * A_PtrSize, iSize := 0, sz := 0, pcbSize:=8+2*A_PtrSize, offsets := {x: (20+A_PtrSize*2), y: (24+A_PtrSize*2)}, uRawInput

        static axes := {x: 1, y: 2}

        ; Get hDevice from RAWINPUTHEADER to identify which mouse this data came from
        VarSetCapacity(header, pcbSize, 0)
        If (!DllCall("GetRawInputData", "UPtr", lParam, "uint", 0x10000005, "UPtr", &header, "Uint*", pcbSize, "Uint", pcbSize) or ErrorLevel)
            Return 0
        ThisMouse := NumGet(header, 8, "UPtr")

        ; Find size of rawinput data - only needs to be run the first time.
        if (!iSize){
            r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", iSize, "UInt", 8 + (A_PtrSize * 2))
            VarSetCapacity(uRawInput, iSize)
        }
        sz := iSize ; param gets overwritten with # of bytes output, so preserve iSize
        ; Get RawInput data
        r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", &uRawInput, "UInt*", sz, "UInt", 8 + (A_PtrSize * 2))

        x := 0, y := 0  ; Ensure we always report a number for an axis. Needed?
        x := NumGet(&uRawInput, offsets.x, "Int")
        y := NumGet(&uRawInput, offsets.y, "Int")

        this.Callback.(ThisMouse, x, y)

        ;~ ; There is no message for "Stopped", so simulate one
        ;~ fn := this.TimeoutFn
        ;~ SetTimer, % fn, -50
    }

    ;~ TimeoutFunc(){
        ;~ this.Callback.("", 0, 0)
    ;~ }

}

这个怎么用?