How to interact with the Windows API using Java and the JNA (Java Native Access)?. I'm trying to make the mouse do something by queuing a mouse event on the mouse input stream, and the code works, in that the SendInput(...)
method returns 1 suggesting that it has successfully queued the event, but yet the mouse itself does nothing.
My 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:
Doing more reading, and it seems that my understanding of arrays with JNA is deficient, that I have to think in terms of C arrays where an array is simply a pointer to a region of contiguous memory. More to come (I hope!).
The first step to fix mouse (or keyboard) issues is to disconnect and reconnect the mouse on the computer, or to connect the mouse to another USB port. Also, if you 're using a Wireless mouse replace its batteries.
To hold the mouse, keep your thumb on the side of the mouse, index finger on the left button, and middle finger on the right button. While holding the mouse relax your hand and make sure your hand is straight with your arm. You should never have your wrist at an angle while using the mouse.
JNA document Using Structures And Unions reads:
Unions are generally interchangeable with Structures, but require that you indicate which union field is active with the
setType
method before it can be properly passed to a function call.
I guess you missed setType
part. Also, when using MOUSEEVENTF_ABSOLUTE
, dx
and dy
are specified as the coordinate of the mouse, not pixels.
Following works:
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));
...
}
Call the toArray() method on your structure to obtain a contiguous block of memory.
INPUT input = new INPUT();
INPUT[] arg = (INPUT[])input.toArray(1);
Alternatively, you can simply declare an alternate method mapping for SendInput:
DWORD SendInput(int nInputs, INPUT pInputs, int cbSize);
However, there may be something else going on (permissions, perhaps? see MS notes on UIPI), since your example ought to work (at least with a single array element).
EDIT: the Union.setType() answer is indeed the correct one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With