2011-12-06 21 views
10

Estoy tratando de aprender a interactuar con la API de Windows usando Java y el JNA (Java Native Access), pero estoy en un bloqueo de ruta. Estoy tratando de hacer que el mouse haga algo al poner en cola un evento de mouse en la secuencia de entrada del mouse, y el código funciona, porque el método SendInput(...) devuelve 1 sugiriendo que ha puesto en cola exitosamente el evento, pero el mouse no hace nada.Cómo mover (o hacer cualquier cosa con) el mouse

Mi SSCCE:

Editar: editado a llenar el campo dwFlags. Probé varias combinaciones de constantes por sí mismos o por bits, o combiné sin éxito todavía. Una vez más, el método devuelve 1 SendInput como debe sugerir un método de funcionamiento, pero el ratón no se mueve:

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 
    } 
} 

Edición 2:

hacer más lectura, y parece que mi comprensión de matrices con JNA es deficiente, que tengo que pensar en términos de matrices C donde una matriz es simplemente un puntero a una región de memoria contigua. Más por venir (¡espero!).

+0

Offtopic: Siempre es un placer ver que ser agradable, tranquilo y agradable con la gente. Eres una de las personas que realmente busco por aquí. Felices vacaciones; y un gran año 2017! – GhostCat

+1

@GhostCat: Su primera declaración es algo divertida, pero la segunda es muy amable. Y admiro a usted, sus habilidades y su deseo de difundir su conocimiento a los demás. –

Respuesta

9

documento JNA Using Structures And Unions lee:

sindicatos son generalmente intercambiables con las Estructuras, pero requieren que usted indica qué campo es la unión activa con el método setType antes de que pueda ser debidamente pasa a una llamada de función.

Supongo que te has perdido setType parte. Además, al usar MOUSEEVENTF_ABSOLUTE, dx y dy se especifican como la coordenada del mouse, no de los píxeles.

obras Siguiendo:

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)); 
    ... 
} 
+3

¡Santa chit! 'setType (...)' ¿Lo era? Había asumido erróneamente que establecer el campo de tipo de la variable de entrada sería suficiente, pero estaba mal. Con tus correcciones, mi código funciona. No puedo agradecerte lo suficiente! –

2
input.input.mi.dwFlags = new DWORD(0); 

No especificó ninguna de las marcas de entrada del mouse, por lo que no se ingresó el mouse.

+0

Gracias! déjame ver eso! –

+0

Consulte editar mi pregunta y el código actualizado. ¡Toda ayuda es muy apreciada! –

+0

Gracias de nuevo por sus excelentes sugerencias; ¡fueron de lo más útil! –

3

Llame al método toArray() en su estructura para obtener un bloque contiguo de memoria.

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

Alternativamente, puede simplemente declara un mapeo método alternativo para SendInput: (? Permisos, tal vez vea MS notas sobre UIPI)

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

Sin embargo, puede haber algo más en juego, ya que su el ejemplo debería funcionar (al menos con un solo elemento de matriz).

EDITAR: la respuesta Union.setType() es la correcta.

+0

¡Gracias por sus valiosas sugerencias! Lo agradezco mucho He votado a favor de tu publicación y solo deseo poder dividir la bonificación entre todos los que ayudaron. –

Cuestiones relacionadas