2017-05-28 8 views
1

私は一般的にマウスの動きを画面に対して相対的にキャプチャする方法を知っていますが、マウスの動きが画面上のマウスの位置から独立して使用されているゲームではどうでしょうか?Autohotkeyで生のマウス入力をキャプチャして送信するにはどうすればよいですか?

たとえば、ゲームではカーソルは非表示になっていますが、画面上を移動する余地よりもはるか遠くにマウスを無限に左に移動して円を回すことができます。ゲームは目に見えないマウスを中央にロックしたり、ウィンドウの端に当たるまで動かしたりすることができますが、その時点で画面に対するマウスの動きを記録しようとする試みは無意味です。

生のマウス入力をキャプチャ/送信するにはどうすればよいですか。たとえば、マウス入力で左に1000度回転させ、左に1000度回転するプレーヤーからのマウス入力を記録するようにプレイヤーに指示するには、どうすればよいのですか?

私の目標は、マウス入力を含むプレーヤーのさまざまな制御を記録して、ユーザーの入力を記録し再生するシステムの1つを作成することです。私はahkドキュメントとGoogleの全面を検索し、生のマウス入力をキャプチャして送信することについて何も見つけ出しませんでした。

答えて

1

これは、evilCというAHKフォーラムの素晴らしいユーザーによってあなたの世話をしてくれました。

これはmouse deltaと呼ばれ、生のマウス入力の変化を追跡します。

私はマウスデルタスクリプトのいくつかの異なる変形の1つを投稿しました。上記のリンクをたどって、彼が行ったすべてのものを見てください。

これも私の仕事ではありません。

; 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) 
    ;~ } 

} 
関連する問題