You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下Python获取鼠标delta(原始移动数据)的技术方案咨询

Got it, let's tackle this problem—you need raw mouse delta data on Windows, bypassing cursor position limitations (perfect for games that lock or reset the cursor). Here's how to do it with Python, using low-level Windows APIs directly, just like that AutoHotkey implementation you referenced:

核心思路:Windows Raw Input API

Windows provides the Raw Input API, which is designed specifically to grab unprocessed input data from devices—including the exact mouse movement delta (X/Y increments)—completely bypassing the system's cursor position handling. This is exactly what you need: no matter how the game resets or locks the cursor, you'll get the real movement data.

实现代码(纯Python,无需额外库)

We'll use ctypes (a built-in Python library) to call Windows APIs directly, so you don't need to install any third-party packages:

import ctypes
from ctypes import wintypes

# Load Windows user32 library
user32 = ctypes.WinDLL('user32', use_last_error=True)

# Define required Windows API structures
class RAWINPUTDEVICE(ctypes.Structure):
    _fields_ = [
        ("usUsagePage", wintypes.WORD),
        ("usUsage", wintypes.WORD),
        ("dwFlags", wintypes.DWORD),
        ("hwndTarget", wintypes.HWND)
    ]

class RAWINPUTHEADER(ctypes.Structure):
    _fields_ = [
        ("dwType", wintypes.DWORD),
        ("dwSize", wintypes.DWORD),
        ("hDevice", wintypes.HANDLE),
        ("wParam", wintypes.WPARAM)
    ]

class RAWMOUSE(ctypes.Structure):
    _fields_ = [
        ("usFlags", wintypes.WORD),
        ("ulButtons", wintypes.DWORD),
        ("usButtonFlags", wintypes.WORD),
        ("usButtonData", wintypes.WORD),
        ("ulRawButtons", wintypes.DWORD),
        ("lLastX", wintypes.LONG),
        ("lLastY", wintypes.LONG),
        ("ulExtraInformation", wintypes.DWORD)
    ]

class RAWINPUT(ctypes.Structure):
    _fields_ = [
        ("header", RAWINPUTHEADER),
        ("data", ctypes.Union(
            _fields_ = [
                ("mouse", RAWMOUSE),
                # We only care about mouse data, ignore other device types
            ]
        ))
    ]

# Constants for Raw Input API
RIDEV_INPUTSINK = 0x00000100  # Allow window to receive input even when not in foreground
RIM_TYPEMOUSE = 0x00000000     # Specify mouse input type
WM_INPUT = 0x00FF              # Window message for raw input

def register_raw_mouse(hwnd):
    """Register the mouse device for raw input capture"""
    rid = RAWINPUTDEVICE()
    rid.usUsagePage = 0x01  # Generic desktop control page
    rid.usUsage = 0x02       # Mouse device
    rid.dwFlags = RIDEV_INPUTSINK
    rid.hwndTarget = hwnd
    
    if not user32.RegisterRawInputDevices(ctypes.byref(rid), 1, ctypes.sizeof(rid)):
        raise ctypes.WinError(ctypes.get_last_error())

class HiddenInputWindow:
    """Create a hidden window to receive raw input messages"""
    def __init__(self):
        self.hwnd = None
        self.running = True

        # Window procedure to handle messages
        def wndproc(hwnd, msg, wparam, lparam):
            if msg == WM_INPUT:
                # Get size of raw input data
                data_size = wintypes.DWORD()
                user32.GetRawInputData(lparam, RIM_TYPEMOUSE, None, ctypes.byref(data_size), ctypes.sizeof(RAWINPUTHEADER))
                
                # Allocate memory and read the raw input data
                raw_input = RAWINPUT()
                user32.GetRawInputData(lparam, RIM_TYPEMOUSE, ctypes.byref(raw_input), ctypes.byref(data_size), ctypes.sizeof(RAWINPUTHEADER))
                
                # Extract mouse delta values
                delta_x = raw_input.data.mouse.lLastX
                delta_y = raw_input.data.mouse.lLastY
                if delta_x != 0 or delta_y != 0:
                    print(f"Raw Mouse Delta: X={delta_x}, Y={delta_y}")
            
            elif msg == 0x0010:  # WM_CLOSE message
                self.running = False
                return 0
            
            return user32.DefWindowProcW(hwnd, msg, wparam, lparam)

        # Register window class
        wc = wintypes.WNDCLASSEXW()
        wc.cbSize = ctypes.sizeof(wc)
        wc.lpfnWndProc = ctypes.WINFUNCTYPE(wintypes.LRESULT, wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM)(wndproc)
        wc.lpszClassName = "RawMouseCaptureWindow"
        user32.RegisterClassExW(ctypes.byref(wc))

        # Create hidden window
        self.hwnd = user32.CreateWindowExW(
            0, wc.lpszClassName, "", 0,
            0, 0, 0, 0, None, None, None, None
        )
        if not self.hwnd:
            raise ctypes.WinError(ctypes.get_last_error())

        # Register mouse for raw input
        register_raw_mouse(self.hwnd)

    def start(self):
        """Start the message loop to listen for input"""
        msg = wintypes.MSG()
        while self.running and user32.GetMessageW(ctypes.byref(msg), None, 0, 0) != 0:
            user32.TranslateMessage(ctypes.byref(msg))
            user32.DispatchMessageW(ctypes.byref(msg))

if __name__ == "__main__":
    print("Listening for raw mouse delta data... Press Ctrl+C to exit")
    try:
        window = HiddenInputWindow()
        window.start()
    except KeyboardInterrupt:
        print("\nExiting...")

关键细节解释

  • Hidden Window: Windows requires a window handle to receive input messages, so we create a fully hidden window that won't interfere with your game or other apps.
  • Raw Input Registration: Using RIDEV_INPUTSINK ensures we capture mouse data even if the hidden window isn't the active foreground window (critical for games running in fullscreen).
  • Delta Values: The lLastX and lLastY fields from the RAWMOUSE struct give you the raw movement increments—positive values mean right/down, negative mean left/up—completely independent of cursor position.

注意事项

  • For fullscreen exclusive games, you may need to run the Python script with administrator privileges to ensure input capture works correctly.
  • This implementation uses the exact same underlying Windows API as the AutoHotkey script you referenced, so it will deliver identical raw mouse data.

内容的提问来源于stack exchange,提问作者AlexAndHisScripts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 23:48:12