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

使用JNA调用Windows SendInput实现鼠标移动失效问题排查

你的代码返回result=1说明SendInput调用成功了,但鼠标不动的核心原因是没有正确使用绝对坐标模式,以及坐标值未按Windows要求做归一化处理。

问题拆解

  1. 坐标模式错误:MOUSEEVENTF_MOVE默认是相对移动模式,直接传入屏幕像素值(比如1000)不会触发绝对位置移动,必须加上MOUSEEVENTF_ABSOLUTE标志声明绝对坐标。
  2. 坐标值未归一化:Windows要求SendInput的绝对坐标dx/dy必须是0-65535之间的数值(对应屏幕左上角到右下角的范围),直接传像素值无效。
  3. 不必要的装箱类型:参数用Long装箱类型会额外创建对象,改用基本类型long更高效。

修正后的代码

import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinUser.INPUT;
import static com.sun.jna.platform.win32.WinUser.INPUT.INPUT_MOUSE;
import static com.sun.jna.platform.win32.WinUser.MOUSEEVENTF_MOVE;
import static com.sun.jna.platform.win32.WinUser.MOUSEEVENTF_ABSOLUTE;

public class Test {

    public static void main(String[] a) {
        // 示例:移动到屏幕(1000, 1000)的像素位置
        moveMouse(1000, 1000);
    }

    /**
     * @param x 目标屏幕X像素坐标
     * @param y 目标屏幕Y像素坐标
     */
    public static void moveMouse(long x, long y) {
        // 获取当前屏幕分辨率
        int screenWidth = User32.INSTANCE.GetSystemMetrics(0); // SM_CXSCREEN
        int screenHeight = User32.INSTANCE.GetSystemMetrics(1); // SM_CYSCREEN

        // 将像素坐标转换为SendInput要求的0-65535范围的绝对坐标
        long normalizedX = (x * 65535L) / screenWidth;
        long normalizedY = (y * 65535L) / screenHeight;

        INPUT input = new INPUT();
        input.type = new DWORD(INPUT_MOUSE);
        input.input.mi.dx = new LONG(normalizedX);
        input.input.mi.dy = new LONG(normalizedY);
        input.input.mi.time = new DWORD(0);
        // 同时设置移动标志和绝对坐标标志
        input.input.mi.dwFlags = new DWORD(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE);

        INPUT[] inputArray = {input};
        // input.size()对应C++里的sizeof(INPUT),是单个结构体的字节大小,此用法正确
        DWORD result = User32.INSTANCE.SendInput(new DWORD(1), inputArray, input.size());

        System.out.println("result = " + result.longValue());
        System.out.println("size = " + input.size());
    }
}

额外说明

  • 如果需要相对移动(比如相对于当前位置偏移N像素),去掉MOUSEEVENTF_ABSOLUTE标志,直接传入正负偏移值即可,但注意系统鼠标加速可能影响实际移动距离。
  • SendInput的第三个参数确实是单个INPUT结构体的大小,和数组无关,你之前的input.size()用法是正确的,无需纠结数组字节数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:31:01