【问题标题】:How to move (or do anything with) the mouse如何移动(或使用)鼠标
【发布时间】:2012-01-14 13:23:46
【问题描述】:

我正在尝试学习如何使用 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
   }
}

编辑 2:

做更多的阅读,似乎我对 JNA 数组的理解是不足的,我必须从 C 数组的角度来思考,其中数组只是指向连续内存区域的指针。以后还会有更多(我希望!)。

【问题讨论】:

    标签: java winapi mouse jna


    【解决方案1】:
    input.input.mi.dwFlags = new DWORD(0);
    

    您没有指定任何鼠标输入标志,因此没有鼠标输入。

    【讨论】:

      【解决方案2】:

      在你的结构上调用 toArray() 方法来获得一块连续的内存。

      INPUT input = new INPUT();
      INPUT[] arg = (INPUT[])input.toArray(1);
      

      或者,您可以简单地为 SendInput 声明一个替代方法映射:

      DWORD SendInput(int nInputs, INPUT pInputs, int cbSize);
      

      但是,可能还有其他事情发生(也许是权限?请参阅关于 UIPI 的 MS 说明),因为您的示例应该可以工作(至少使用单个数组元素)。

      编辑:Union.setType() 答案确实是正确的。

      【讨论】:

        【解决方案3】:

        JNA 文档Using Structures And Unions 内容如下:

        联合通常可以与结构互换,但要求您使用 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));
            ...
        }
        

        【讨论】:

          猜你喜欢
          • 2011-12-24
          • 1970-01-01
          • 1970-01-01
          • 2021-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多