2011-12-06 12 views
10

Sto cercando di imparare come interagire con l'API di Windows utilizzando Java e JNA (Java Native Access), ma sono su un blocco stradale. Sto cercando di fare qualcosa facendo accodando un evento del mouse sul flusso di input del mouse, e il codice funziona, in quanto il metodo SendInput(...) restituisce 1 suggerendo che ha accodato correttamente l'evento, ma il mouse stesso non fa nulla.Come spostare (o fare qualsiasi cosa con) il mouse

mio SSCCE:

Edit: a cura di compilare il campo dwFlags. Ho provato diverse combinazioni di costanti da sole o bit o combinate senza successo ancora. Anche in questo caso, il metodo SendInput restituisce 1 come dovrebbe suggerire un metodo di funzionamento, ma il mouse non si muove:

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

Edit 2:

Fare di più la lettura, e sembra che la mia comprensione di gli array con JNA sono carenti, che devo pensare in termini di array C in cui un array è semplicemente un puntatore a una regione di memoria contigua. Altro a venire (spero!).

+0

offtopic: E 'sempre un piacere vedervi essere bello, rilassante e accogliente con la gente. Sei una delle persone che cerco davvero da queste parti. Buone vacanze; e un grande anno 2017! – GhostCat

+1

@GhostCat: la tua prima affermazione è piuttosto divertente, ma la tua seconda è troppo gentile. E guardo a te, alle tue capacità e al tuo desiderio di diffondere la tua conoscenza agli altri. –

risposta

9

documento JNA Using Structures And Unions legge:

sindacati sono generalmente intercambiabili con le strutture, ma richiedono di indicare quale campo unione è attiva con il metodo setType prima che possa essere adeguatamente passato a una chiamata di funzione.

Immagino abbiate perso la parte setType. Inoltre, quando si utilizza MOUSEEVENTF_ABSOLUTE, dx e dy vengono specificati come le coordinate del mouse, non i pixel.

seguenti lavori:

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

Chit santo! 'setType (...)' è stato! Avevo erroneamente pensato che l'impostazione del campo di testo della variabile di input sarebbe stata sufficiente, ma sbagliata. Con le tue correzioni il mio codice funziona. Non posso ringraziarti abbastanza! –

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

Non è stato specificato nessuno dei flag di input del mouse, quindi non è stato inserito il mouse.

+0

Grazie! fammi esaminare questo! –

+0

vedi modifica alla mia domanda e codice aggiornato. Tutto l'aiuto è molto apprezzato! –

+0

Grazie ancora per i tuoi fantastici suggerimenti; sono stati molto utili! –

3

Chiamare il metodo toArray() sulla struttura per ottenere un blocco di memoria contiguo.

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

In alternativa, si può semplicemente dichiarare un metodo di mappatura alternativo per SendInput: (? Permessi, forse vedere MS note sul UIPI)

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

Tuttavia, ci può essere qualcos'altro, dal momento che il l'esempio dovrebbe funzionare (almeno con un singolo elemento dell'array).

MODIFICA: la risposta Union.setType() è effettivamente quella corretta.

+0

Grazie per i preziosi suggerimenti !! Lo apprezzo molto. Ho votato in su il tuo post e vorrei solo poter dividere la taglia tra tutti quelli che mi hanno aiutato. –

Problemi correlati