I am trying to create a localized implementation of cloud gaming where a user's own PC serves as the server. What I am trying to achieve is the last piece stopping me. That is implementing hardware mouse movements. This is where Windows' SendInput()
comes into play.
The issue I have right now is that My entire code is based on Kotlin/Java. So, I don't exactly know how to replicate the functions of SendInput()
in Java other than to use JNA to access C++ functions. More specifically access SendInput()
. But, here's where I'm stuck. My Java code compiles, but doesn't execute when called.
#include<windows.h>
#include<iostream>
using namespace std;
void moveMouse(int x, int y) {
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = x;
input.mi.dy = y;
input.mi.time = 0;
input.mi.dwFlags = MOUSEEVENTF_MOVE;
UINT qwe = SendInput(1, &input, sizeof(input));
cout<< qwe;
}
look into the comments in the code below.
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinUser.INPUT;
//import static com.sun.jna.Native.sizeof;//compilation error 'sizeof(int)' has private access in 'com.sun.jna.Native'
import static com.sun.jna.platform.win32.WinUser.INPUT.INPUT_MOUSE;
public class Test {
public static void main(String[] a) {
moveMouse(
1_000L,
1_000L
);
}
/**
* @param x change required in x co-ordinate
* @param y change required in y co-ordinate
*
*/
public static void moveMouse(Long x, Long y) {
INPUT input = new INPUT();
input.type = new DWORD(INPUT_MOUSE);
input.input.mi.dx = new LONG(x);
input.input.mi.dy = new LONG(y);
input.input.mi.time = new DWORD(0);
input.input.mi.dwFlags = new DWORD(0x0001L);
INPUT[] inputArray = {input};
DWORD result = User32.INSTANCE.SendInput(new DWORD(1), inputArray, input.size());
// sizeof (used below in the commented code) returns the compilation error
// 'sizeof(int)' has private access in 'com.sun.jna.Native'
// I got the idea to use sizeof from another StackOverflow post
// DWORD result = User32.INSTANCE.SendInput(new DWORD(1), inputArray, sizeof(input));
System.out.println("result = " + result.longValue());
System.out.println("size = " + input.size());
}
}
result = 1
size = 40
You'll see that in SendInput
, I'm sending the size of the input variable instead of the array's size which is what I'm supposed to send. To get the size of array in bytes, I got the idea to use sizeof
, but, as you have seen above in the comments, you'll have already understood why I can't use it as I can't import a private function.
The mouse doesn't move a pixel when the Java code is executed.
I forgot to net type. Didn't realize this was necessary. Anyways, here is the code -
public static void moveMouse(Long x, Long y) {
INPUT input = new INPUT();
input.type = new DWORD(INPUT_MOUSE);
input.input.setType("mi");//--------------------------------------added this
input.input.mi.dx = new LONG(x);
input.input.mi.dy = new LONG(y);
input.input.mi.time = new DWORD(0);
input.input.mi.dwFlags = new DWORD(0x0001L);
INPUT[] inputArray = {input};
DWORD result = User32.INSTANCE.SendInput(new DWORD(1), inputArray, input.size());
}
For anybody having this issue, this function can be straight up copy pasted and it should work.