Hoe de muis te verplaatsen (of iets te doen met)

Ik probeer te leren omgaan met de Windows API met behulp van Java en de JNA (Java Native Access), maar ben in de problemen. Ik probeer de muis iets te laten doen door een muisgebeurtenis in een wachtrij te plaatsen op de muisinvoerstream, en de code werkt, in die zin dat de SendInput (...) methode 1 retourneert en suggereert dat het met succes is in de wachtrij geplaatst, maar toch doet de muis zelf niets.

Mijn SSCCE :

Edit: edited to fill in the dwFlags field. I've tried several combinations of constants either by themselves or bit-or combined without success still. Again, the SendInput method returns 1 as it should suggesting a functioning method, but the mouse doesn't budge:

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:

Meer lezen, en het lijkt erop dat mijn begrip van arrays met JNA tekortschiet, dat ik moet denken in termen van C-arrays waarbij een array eenvoudigweg een verwijzing is naar een regio met aaneengesloten geheugen. Er komt nog meer aan (hoop ik!).

10
Offtopic: Het is altijd een plezier om je aardig, ontspannen en vriendelijk te zien met mensen. Jij bent een van de mensen die ik hier zocht. Fijne vakantie; en een geweldig jaar 2017!
toegevoegd de auteur GhostCat, de bron
@GhostCat: je eerste uitspraak is enigszins grappig, maar je tweede is te vriendelijk. En ik kijk naar je op, je capaciteiten en je verlangen om je kennis aan anderen te verspreiden.
toegevoegd de auteur Hovercraft Full Of Eels, de bron

3 antwoord

JNA-document Structuren en unies gebruiken luidt als volgt:

Vakbonden zijn over het algemeen uitwisselbaar met structuren, maar vereisen dat u aangeeft welk vakveld actief is met de setType -methode voordat het correct kan worden doorgegeven aan een functieaanroep.

Ik vermoed dat je het onderdeel setType hebt gemist. Ook worden bij gebruik van MOUSEEVENTF_ABSOLUTE , dx en dy opgegeven als de coördinaat van de muis, niet als pixels.

Volgende werken:

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));
    ...
}
10
toegevoegd
Holy chit! setType (...) was het! Ik had ten onrechte aangenomen dat het instellen van het invoerveld van de invoervariabele voldoende zou zijn, maar dat het fout was. Met uw correcties werkt mijn code. Ik kan je niet genoeg bedanken!
toegevoegd de auteur Hovercraft Full Of Eels, de bron

Roep de methode toArray() op uw structuur aan om een ​​aaneengesloten blok geheugen te verkrijgen.

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

Als alternatief kunt u eenvoudig een alternatieve methodemapping voor SendInput declareren:

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

Er kan echter nog iets anders aan de hand zijn (toestemmingen, misschien? Zie MS-notities op UIPI), omdat je voorbeeld zou moeten werken (tenminste met een enkel array-element).

EDIT: het antwoord Union.setType() is inderdaad de juiste.

3
toegevoegd
Bedankt voor je waardevolle suggesties !! Ik waardeer het enorm. Ik heb je bericht gesteund en ik wou dat ik de premie kon verdelen over iedereen die heeft geholpen.
toegevoegd de auteur Hovercraft Full Of Eels, de bron
input.input.mi.dwFlags = new DWORD(0);

U hebt geen van de muisinvoervlaggen opgegeven, dus er was geen muisinvoer.

2
toegevoegd
Bedankt! laat me daar eens naar kijken!
toegevoegd de auteur Hovercraft Full Of Eels, de bron
zie de bewerking van mijn vraag en bijgewerkte code. Alle hulp wordt enorm op prijs gesteld!
toegevoegd de auteur Hovercraft Full Of Eels, de bron
Nogmaals bedankt voor je geweldige suggesties; ze waren zeer behulpzaam!
toegevoegd de auteur Hovercraft Full Of Eels, de bron