2017-05-28 7 views
1

Ich weiß, wie man Mausbewegungen im Allgemeinen relativ zum Bildschirm erfasst, aber was ist mit Spielen, bei denen Mausbewegungen unabhängig von der Position der Maus auf dem Bildschirm verwendet werden?Wie kann ich rohe Mauseingaben in Autohotkey erfassen und senden?

Zum Beispiel in einem Spiel ist der Cursor versteckt, aber Sie können Ihre Maus unendlich weiter nach links bewegen und in Kreisen drehen, weit mehr als es Platz für Ihre Maus auf dem Bildschirm zu bewegen ist. Das Spiel könnte Ihre unsichtbare Maus in die Mitte sperren oder sich bewegen lassen, bis sie den Rand des Fensters erreicht, aber an diesem Punkt ist jeder Versuch, die Bewegung der Maus relativ zum Bildschirm aufzuzeichnen, nutzlos.

Also wie kann ich rohe Mauseingabe erfassen/senden. Zum Beispiel, wenn ich dem Spieler sagen möchte, dass er sich mit der Maus um 1000 Grad nach links dreht und die Mauseingabe von einem Spieler aufnimmt, der sich um 1000 Grad nach links dreht, wie kann ich beides tun?

Mein Ziel ist es schließlich, die verschiedenen Steuerelemente eines Spielers einschließlich der Mauseingabe aufzuzeichnen, um eines dieser Systeme zu erstellen, die Benutzereingaben aufzeichnen und wiedergeben. Ich habe überall in der ahk-Dokumentation und Google gesucht und nichts über das Erfassen und Senden roher Mauseingabe gefunden.

Antwort

1

Dies wurde für Sie von einem fantastischen Benutzer in den AHK-Foren namens evilC erledigt.

Es heißt mouse delta und verfolgt Änderungen in rohen Mauseingabe.

Ich habe eine der wenigen verschiedenen Varianten seines Maus-Delta-Skripts gepostet. Stelle sicher, dass du dem obigen Link folgst, um all die verschiedenen zu sehen, die er gemacht hat.

Auch dies ist nicht meine Arbeit.

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

} 
Verwandte Themen