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

不使用外部库实现Python鼠标指针移动报错排查

问题分析与修复

报错核心原因

代码在new_x相关计算处报错,主要有两个问题:

  1. 除零错误:user32.GetSystemMetrics未指定返回值类型,ctypes默认将其视为c_int,部分环境下调用失败会返回0,导致后续new_x / screen_width触发ZeroDivisionError。
  2. API调用不规范:未正确定义GetCursorPos所需的POINT结构体,可能引发内存访问问题或获取错误的光标坐标;且mouse_event属于Windows废弃API,调用逻辑存在潜在兼容性问题。

修复后的代码

import ctypes
import time

# 定义Windows原生POINT结构体,匹配API参数要求
class POINT(ctypes.Structure):
    _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]

MOUSEEVENTF_MOVE = 0x0001
MOUSEEVENTF_ABSOLUTE = 0x8000

target_x = 500
target_y = 500
movement_amount = 50

# 加载user32并指定函数参数/返回值类型,避免类型错误
user32 = ctypes.WinDLL('user32', use_last_error=True)
user32.GetSystemMetrics.argtypes = [ctypes.c_int]
user32.GetSystemMetrics.restype = ctypes.c_int
user32.GetCursorPos.argtypes = [ctypes.POINTER(POINT)]
user32.GetCursorPos.restype = ctypes.c_bool
user32.mouse_event.argtypes = [ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, ctypes.c_ulonglong]

screen_width = user32.GetSystemMetrics(0)
screen_height = user32.GetSystemMetrics(1)

# 提前校验屏幕分辨率有效性,避免除零
if screen_width == 0 or screen_height == 0:
    raise RuntimeError("无法获取有效屏幕分辨率")

while True:
    original_pos = POINT()
    if not user32.GetCursorPos(ctypes.byref(original_pos)):
        raise RuntimeError("无法获取当前光标位置")

    new_x = target_x + movement_amount
    new_y = target_y + movement_amount

    # 计算绝对坐标,限制在0-65535范围内(符合MOUSEEVENTF_ABSOLUTE要求)
    absolute_x = min(max(int(new_x / screen_width * 65535), 0), 65535)
    absolute_y = min(max(int(new_y / screen_height * 65535), 0), 65535)

    user32.mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, absolute_x, absolute_y, 0, 0)
    time.sleep(1)

    # 计算原位置的绝对坐标并返回
    orig_abs_x = int(original_pos.x / screen_width * 65535)
    orig_abs_y = int(original_pos.y / screen_height * 65535)
    user32.mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, orig_abs_x, orig_abs_y, 0, 0)

    time.sleep(10)

关键修复点

  • 定义POINT结构体:严格匹配Windows API的参数结构,避免内存访问异常。
  • 指定函数类型:给所有调用的user32 API明确argtypes和restype,确保ctypes正确处理数据类型转换。
  • 添加前置校验:提前检查屏幕分辨率是否有效,从根源避免除零错误。
  • 限制坐标范围:确保计算出的绝对坐标在MOUSEEVENTF_ABSOLUTE要求的0-65535区间内,避免无效坐标输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:33:31