如何移动(或做任何事情)鼠标

Hov*_*els 9 java mouse winapi jna

我正在尝试学习如何使用Java和JNA(Java Native Access)与Windows API进行交互,但我正处于障碍之中.我试图让鼠标通过在鼠标输入流上排队鼠标事件来做某事,并且代码有效,因为该SendInput(...)方法返回1表示它已成功排队事件,但鼠标本身什么都不做.

我的SSCCE:

编辑:编辑以填写dwFlags字段.我已经尝试了几种常量组合,无论是自己还是比特或组合都没有成功.同样,SendInput方法返回1,因为它应该建议一个正常运行的方法,但鼠标不会让步:

import com.sun.jna.Native;
import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.platform.win32.WinUser.*;
import com.sun.jna.win32.StdCallLibrary;

public class MouseUtils {
   public interface User32 extends StdCallLibrary {
      public static final long MOUSEEVENTF_MOVE = 0x0001L; 
      public static final long MOUSEEVENTF_VIRTUALDESK = 0x4000L; 
      public static final long MOUSEEVENTF_ABSOLUTE = 0x8000L;

      User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
      DWORD SendInput(DWORD dWord, INPUT[] input, int cbSize);
   }

   public static void main(String[] args) {
      INPUT input = new INPUT();
      input.type = new DWORD(INPUT.INPUT_MOUSE);

      input.input.mi.dx = new LONG(500);
      input.input.mi.dy = new LONG(500);
      input.input.mi.mouseData = new DWORD(0);
      input.input.mi.dwFlags = new DWORD(User32.MOUSEEVENTF_MOVE
            | User32.MOUSEEVENTF_VIRTUALDESK | User32.MOUSEEVENTF_ABSOLUTE);
      // input.input.mi.dwFlags = new DWORD(0x8000L);
      input.input.mi.time = new DWORD(0);

      INPUT[] inArray = {input};

      int cbSize = input.size(); // mouse input struct size
      DWORD nInputs = new DWORD(1); // number of inputs
      DWORD result = User32.INSTANCE.SendInput(nInputs , inArray, cbSize);
      System.out.println("result: " + result); // return 1 if the 1 event successfully inserted
   }
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

做更多的阅读,似乎我对使用JNA的数组的理解是有缺陷的,我必须考虑C数组,其中数组只是指向连续内存区域的指针.更多内容(我希望!).

edw*_*rdw 11

JNA文档使用结构和联合读取:

联合通常可以与结构互换,但要求您在将setType方法正确传递给函数调用之前指示哪个联合字段处于活动状态.

我想你错过了setType一部分.此外,使用时MOUSEEVENTF_ABSOLUTE,dxdy被作为鼠标,没有像素的坐标指定.

以下作品:

public interface User32 extends StdCallLibrary {
    ...
    public static final int SM_CXSCREEN = 0x0;
    public static final int SM_CYSCREEN = 0x1;
    int GetSystemMetrics(int index);
}

public static void main(String[] args) {    
    ...
    input.input.setType("mi");
    input.input.mi.dx = new LONG(500 * 65536 / User32.INSTANCE.GetSystemMetrics(User32.SM_CXSCREEN));
    input.input.mi.dy = new LONG(500 * 65536 / User32.INSTANCE.GetSystemMetrics(User32.SM_CYSCREEN));
    ...
}
Run Code Online (Sandbox Code Playgroud)