SendInput() causes infinite loop when used with GetAsyncKeyState() (WinAPI) - c++

So I want to make when you hold down your left click, the mouse starts to click at regular intervals.
In theory all should work right, but in practice, not so well.
Anyways here is the code I am using for the detection and clicking of the mouse:
while (1)
{
if (GetAsyncKeyState(VK_LBUTTON) && GetAsyncKeyState(VK_RBUTTON))
{
if (weapon_selector == nullptr) continue;
if (weapon_selector->isSemiAutomatic)
{
for (Vector2I x : weapon_selector->recoilTable)
{
// Detect for hardware click instead
if (!(GetAsyncKeyState(VK_LBUTTON) & 0x8000) || !GetAsyncKeyState(VK_RBUTTON)) // This right here should detect if you are not holding either of the left or right mouse buttons, and thus abort the movement/clicks of the mouse
{
Utilities::SleepThread(200);
break;
}
Mouse::Click(); // Look in the code below how this is defined
Mouse::MoveRelative_Lerp(x.x, x.y, (int)weapon_selector->repeatDelay); // This is essentially doing this_thread::sleep_for() for around 150 ms every time after the click has happened, which would give plenty of time for the GetAsyncKeyState() function to "update" or whatever if it needed it. This function only moves the mouse, it does not click anywhere!
}
Utilities::SleepThread(200);
}
else
{
...
}
}
Utilities::SleepThread(1);
}
Here is my implementation for the Mouse::Click() function:
void Mouse::Click()
{
INPUT input;
input.type = INPUT_MOUSE;
input.mi.mouseData = NULL;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input.mi.time = 0;
input.mi.dwExtraInfo = NULL;
SendInput(1, &input, sizeof(input));
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(input));
}
I tried pretty much everything I could think of to fix this with no success, like Mouse low level hook, also checking the injected flag in low level mouse hook, Detecting hardware mouse clicking with RegisterRawInputDevices() (with no success either), setting virtualClick variables and all kinds of different checks, no luck.. im tired trying to do this for the past 2 days
I would appreciate it a lot if someone has dealt with this before and can help me.
Minimal reproducible example:
main.cpp
#include <Windows.h>
#include <hidusage.h>
#include <iostream>
#include <cmath>
#include <string>
#include <thread>
#include <atomic>
#include <vector>
#include <fstream>
#include "Mouse.hpp"
#include "Utils.hpp"
#include "Vector2_int.hpp"
struct WeaponData
{
const char* szName;
std::vector<Vector2I> recoilTable;
int repeatDelay;
int magCapacity;
bool isSemiAutomatic;
};
#pragma region Recoil Tables
WeaponData RecoilTables[] = {
{"Revolver", {}, 175, 8, true},
{"SAR", {}, 175, 16, true},
{"SAP (P2000)", {}, 150, 10, true},
{"Python", {}, 150, 6, true},
{"Thompson", {}, 130, 20, false},
{"Custom SMG", {}, 100, 24, false},
{"AK", {}, 133, 30, false},
{"MP5", {}, 100, 30, false},
{"LR300", {}, 120, 30, false},
{"M92", {}, 150, 15, true},
{"M249", {}, 120, 100, false},
{"M39", {}, 200, 20, true},
};
#pragma endregion
void populate_recoil_table(WeaponData* data)
{
if (data->recoilTable.size() > 0) return;
for (int i = 0; i < data->magCapacity; i++)
{
data->recoilTable.push_back({0, 0});
}
}
int main()
{
WeaponData* weapon_selector = &RecoilTables[0];
populate_recoil_table(weapon_selector);
// just to see the movement of the mouse
weapon_selector->recoilTable.at(0).x = 20;
weapon_selector->recoilTable.at(0).y = 20;
while (1)
{
if (GetAsyncKeyState(VK_LBUTTON) && GetAsyncKeyState(VK_RBUTTON))
{
if (weapon_selector == nullptr) continue;
if (weapon_selector->isSemiAutomatic)
{
for (Vector2I x : weapon_selector->recoilTable)
{
if (!(GetAsyncKeyState(VK_LBUTTON) & 0x8000) || !(GetAsyncKeyState(VK_RBUTTON) & 0x8000))
{
puts("stopped bcs no buttons hold");
Utilities::SleepThread(200);
break;
}
puts("clicking");
Mouse::Click();
Utilities::SleepThread(weapon_selector->repeatDelay);
}
Utilities::SleepThread(200);
}
else
{
for (Vector2I x : weapon_selector->recoilTable)
{
if (!GetAsyncKeyState(VK_LBUTTON) || !GetAsyncKeyState(VK_RBUTTON)) { Utilities::SleepThread(200); break; }
Mouse::MoveRelative_Lerp(x.x, x.y, (int)weapon_selector->repeatDelay);
}
Utilities::SleepThread(200);
}
}
Utilities::SleepThread(1);
}
}
Mouse::Click() function
void Mouse::Click()
{
INPUT input;
input.type = INPUT_MOUSE;
input.mi.mouseData = NULL;
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
input.mi.dx = 0;
input.mi.dy = 0;
input.mi.time = 0;
input.mi.dwExtraInfo = NULL;
SendInput(1, &input, sizeof(input)); // First send UP event to "unclick" our mouse button
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; // Then send DOWN event to click and hold the button
SendInput(1, &input, sizeof(input));
input.mi.dwFlags = MOUSEEVENTF_LEFTUP; // Then send UP again to release it to simulate a click
SendInput(1, &input, sizeof(input));
}
Utilities::SleepThread() function
void SleepThread(uint32_t milliseconds)
{
std::chrono::high_resolution_clock::time_point target = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(milliseconds);
while (std::chrono::high_resolution_clock::now() < target)
{
std::this_thread::yield();
}
}
Things to note for the example:
Vector2I is essentially struct with 2 ints: x and y, with some function to add,subtract,etc..
weapon_selector->recoilTable is initialized, its not emtpy! Look at populate_recoil_table() function
The code is compiled with C++17 (MSVC compiler/Visual Studio 2019)
EDIT: I fixed my issue
I had to first "unpress" my button then send DOWN message again, idk why i didnt think of it earlier, the only downside is that the last message before the function ends is DOWN, so the mouse is "stuck" for a little bit (cannot be noticed) but it updates straight away if your physical button is not pressed.
Fixed click function:
void Mouse::Click()
{
INPUT input;
input.type = INPUT_MOUSE;
input.mi.mouseData = NULL;
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
input.mi.dx = 0;
input.mi.dy = 0;
input.mi.time = 0;
input.mi.dwExtraInfo = NULL;
SendInput(1, &input, sizeof(input));
Utilities::SleepThread(10); // The application im targeting doesnt get the update if its instant mouse press, thus waiting a little
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(input));
}

Related

Why do I receive key release event when key release is not in event mask. (xcb)

I am making a simple xcb application and I noticed that when XCB_EVENT_MASK_KEY_PRESS is in the event mask and XCB_EVENT_MASK_KEY_RELEASE is not in the event mask I still get XCB_KEY_RELEASE events in my event loop if I hold down a key so that it repeats the key press event. Surely if XCB_EVENT_MASK_KEY_RELEASE is not in the event mask I should never get an XCB_KEY_RELEASE event?
Minimum reproducible example:
Run and hold down a key for a few seconds so that the keypress event repeats. This causes the key release event despite XCB_EVENT__MASK_KEY_RELEASE not being in the event mask.
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
/* notice that the event mask does not conatin XCB_EVENT_MASK_KEY_RLEASE */
const uint32_t EVENT_MASK
= XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_KEY_PRESS;
int main()
{
int screenNum;
xcb_connection_t* xcon = xcb_connect(NULL, &screenNum);
const xcb_setup_t* xsetup = xcb_get_setup(xcon);
xcb_screen_t* screen;
{
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xsetup);
for (int i = 0; i < screenNum; i++)
xcb_screen_next(&iter);
screen = iter.data;
}
xcb_window_t window = xcb_generate_id(xcon);
uint32_t winvals[] = { screen->white_pixel, EVENT_MASK };
xcb_create_window(
xcon,
XCB_COPY_FROM_PARENT,
window,
screen->root,
10, 10,
150, 150,
10,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, winvals);
xcb_map_window(xcon, window);
xcb_flush(xcon);
xcb_generic_event_t* event;
while ((event = xcb_wait_for_event(xcon))) {
switch (event->response_type & ~0x80) {
case XCB_EXPOSE: {
// TODO: draw something
xcb_flush(xcon);
break;
}
case XCB_KEY_PRESS: {
xcb_key_press_event_t* kp = (xcb_key_press_event_t*)event;
printf("key pressed: %u\n", kp->detail);
break;
}
case XCB_KEY_RELEASE: {
puts("KEY RELEASE EVENT?!");
break;
}
default: {
printf("unknown event. type = %u\n", event->response_type);
break;
}
}
free(event);
}
xcb_disconnect(xcon);
return 0;
}

Is there a way to emulate key presses on Windows with low latency?

I am trying to control a windows application through c++. This is my code for mouse clicks:
// info is a WINDOWINFO struct retrieved with GetWindowInfo()
void click(int x, int y) {
// move mouse to given position plus the position of the top left corner of the window
SetCursorPos(info.rcWindow.left + x, info.rcWindow.top + y)
INPUT Input = { 0 };
// left mouse button down
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
::SendInput(1, &Input, sizeof(INPUT));
// left mouse button up
::ZeroMemory(&Input, sizeof(INPUT));
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
::SendInput(1, &Input, sizeof(INPUT));
}
It works, but the latency (~120ms) is too great for my project. Is there a way to reduce it? I only need to control a single window, so the call to the operating system seems excessive, but I couldn't find any examples of directly injecting mouse input to a window online.

Detect left mouse button down after sending left mouse button up

I am writing a program that scans if the Left Mouse Button is held down, then sends a left mouse button up and continues after that. The problem is, since I am sending a left mouse button up, the program will not continue because the left mouse button is not being held down anymore.
Here is some pseudo:
if(GetKeyState(VK_LBUTTON) < 0){
Sleep(10);
mouse_event(MOUSEEVENTF_LEFTUP, p.x, p.y, 0, 0);
//Rest of code
}
How can I detect the left mouse button being down after this? Would I have to use a driver?
Just use a flag:
bool lButtonWasDown=flase;
if(GetKeyState(VK_LBUTTON) < 0){
Sleep(10);
lButtonWasDown = true;
mouse_event(MOUSEEVENTF_LEFTUP, p.x, p.y, 0, 0);
}
if (lButtonWasDown)
{
// rest of the code for lButtonWasDown = true
}
From reading your description of the program only here is my implementation.
Using the Windows API:
while (true) {
//check if left mouse button is down
if (GetKeyState(VK_LBUTTON) & 0x8000) {
//send left mouse button up
//You might want to place a delay in here
//to simulate the natural speed of a mouse click
//Sleep(140);
INPUT Input = { 0 };
::ZeroMemory(&Input, sizeof(INPUT));
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
::SendInput(1, &Input, sizeof(INPUT));
}
}
You can place this code into a function that you call in a thread if you want to do other things while you forcibly stop people from clicking and dragging.
void noHoldingAllowed() {
//insert code here used above...
}
int main(void) {
std::thread t1(noHoldingAllowed);
//other stuff...
return 0;
{
I haven't tested this code, but it should work
while(programIsRunning)
{
if(GetKeyState(VK_LBUTTON) < 0){
Sleep(10);
mouse_event(MOUSEEVENTF_LEFTUP, p.x, p.y, 0, 0);
// rest of the code
}
It should work since if you have the Lmouse button held while the loop reruns if will trigger the if statement which will then trigger a mouseup event.
note:
You might be able to do while(GetKeyState(VK_LBUTTON) < 0){//code here}

How to automate mouse actions

I need to automate some mouse actions.
I need to do
mousemove1, lbuttondown1, wait1, mousemove1, lbuttonup1, wait1,
mousemove2, lbuttondown2, wait2, mousemove2, lbuttonup2, wait2,
...
The actions have to work regarding screen coordinates. The window which have to accept an event is the top window at this point.
There is a file with data.
For example
500 450 1000 500 300 2000
600 450 1000 600 300 5000
What did I try to do
#include <fstream>
#include <vector>
#include <windows.h>
struct A
{
POINT point1;
unsigned sleep1;
POINT point2;
unsigned sleep2;
A() { point1.x = point1.y = sleep1 = point2.x = point2.y = sleep2 = 0; }
};
void f(const A &a)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, a.point1.x, a.point1.y, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, a.point1.x, a.point1.y, 0, 0);
Sleep(a.sleep1);
mouse_event(MOUSEEVENTF_LEFTUP, a.point2.x, a.point2.y, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, a.point2.x, a.point2.y, 0, 0);
Sleep(a.sleep2);
}
int main()
{
std::vector<A> as;
std::ifstream fin("params.txt");
if (fin) {
A a;
while (fin.good()) {
fin >> a.point1.x;
fin >> a.point1.y;
fin >> a.sleep1;
fin >> a.point2.x;
fin >> a.point2.y;
fin >> a.sleep2;
if (fin.eof()) {
break;
}
as.push_back(a);
}
}
for (;;) {
for (const A &a : as) {
f(a);
}
}
}
Something is happening but I can not understand what is and where is a mistake.
A problem with your code is that you are using mouse_event with screen coordinates rather than normalized absolute coordinates. Normalized absolute coordinates always range between (0,0) in the top-left corner to (65535,65535) in the bottom-right corner, no matter what the desktop size happens to be.
The MouseTo function in the example below accepts screen coordinates as inputs, then uses the dekstop window's size to convert to normalized absolute coordinates. This example uses SendInput, which supersedes mouse_event, but they both use the same coordinates. I'm not sure if mouse_event can take the MOUSEEVENTF_VIRTUALDESK flag, but this is for supporting multi-monitor desktops.
If you wish build this example, start with a new Win32 Console application.
#include <Windows.h>
#include <cmath>
void MouseTo(int x, int y) {
RECT desktop_rect;
GetClientRect(GetDesktopWindow(), &desktop_rect);
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags =
MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | MOUSEEVENTF_MOVE;
input.mi.dx = x * 65536 / desktop_rect.right;
input.mi.dy = y * 65536 / desktop_rect.bottom;
SendInput(1, &input, sizeof(input));
}
void MouseLButton(bool tf_down_up) {
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags = tf_down_up ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(input));
}
void MouseLButtonDown() { MouseLButton(true); }
void MouseLButtonUp() { MouseLButton(false); }
void AnimatedDrag(const POINT& from, const POINT& to) {
static const double iteration_dist = 20;
static const DWORD iteration_delay_ms = 1;
const double dx = to.x - from.x;
const double dy = to.y - from.y;
const double dist = sqrt(dx*dx + dy*dy);
const int count = static_cast<int>(dist / iteration_dist);
MouseTo(from.x, from.y);
MouseLButtonDown();
for(int i=1; i<count; ++i) {
const int x = from.x + static_cast<int>(dx * i / count);
const int y = from.y + static_cast<int>(dy * i / count);
MouseTo(x, y);
Sleep(iteration_delay_ms);
}
MouseTo(to.x, to.y);
MouseLButtonUp();
}
int main() {
// minimize console window
ShowWindow(GetConsoleWindow(), SW_SHOWMINNOACTIVE);
Sleep(500);
// Drag whatever is at the window coordinates in "from" to "to"
const POINT from = {300, 100};
const POINT to = {900, 600};
AnimatedDrag(from, to);
}
Christopher's answer should suffice, but might be a little intimidating to anyone not well-versed with C++, and just trying to hack together a click-utility. This should be easy enough to hack away at for most newbies.
Pardon the use of macros; I'm using them to make the intent of the code a little more English-friendly.
It should right-click on your primary display (unless you changed the X coordinate line as-commented) then shift a few pixels over and left-click to close the Right-click menu prompt, if one was created. You can see what else is available on MSDN for your own custom requirements.
I kept click / unclick / move as seperate actions, so things like drag & drop should be fairly intuitive to perform when starting with all the right ingredients.
#include <Windows.h>
// Uses absolute coords where the primary display starts at 0,0
// That works well with enumerated monitors structures and their reported coords.
#define QUEUE_MV_MOUSE ip.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
#define QUEUE_RC_START_MOUSE ip.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
#define QUEUE_RC_END_MOUSE ip.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
#define QUEUE_LC_START_MOUSE ip.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
#define QUEUE_LC_END_MOUSE ip.mi.dwFlags = MOUSEEVENTF_LEFTUP;
#define SEND_IT SendInput(1, &ip, sizeof(ip));
#define VIRTUAL_X_MODIFIER (65536 / GetSystemMetrics(SM_CXSCREEN));
#define VIRTUAL_Y_MODIFIER (65536 / GetSystemMetrics(SM_CYSCREEN));
int main()
{
INPUT ip;
ip.type = INPUT_MOUSE;
ip.mi.mouseData = 0;
// Change 500 to -500 for a left-hand extended display.
ip.mi.dx = 500 * VIRTUAL_X_MODIFIER;
ip.mi.dy = 1000 * VIRTUAL_Y_MODIFIER;
// Un-comment this Sleep timer if you're debugging in an IDE and need a quick pause.
// Sleep(500);
QUEUE_MV_MOUSE;
SEND_IT;
// Various users advise brief Sleep pauses between queued mouse and keyboard events.
// 500 milliseconds is probably overkill for your automation requirements.
Sleep(500);
QUEUE_RC_START_MOUSE;
SEND_IT;
Sleep(500);
QUEUE_RC_END_MOUSE;
SEND_IT;
Sleep(500);
ip.mi.dx -= 10 * VIRTUAL_X_MODIFIER;
ip.mi.dx -= 10 * VIRTUAL_Y_MODIFIER;
QUEUE_MV_MOUSE;
SEND_IT;
Sleep(500);
QUEUE_LC_START_MOUSE;
SEND_IT;
Sleep(500);
QUEUE_LC_END_MOUSE;
SEND_IT;
return 0;
}

How to simulate a mouse movement

How can I simulate a mouse event causing the pointer to move 500 pixels to the left, then click using C++. How would I do something like this?
Here's some modified Win32 code I had lying around:
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
#define X 123
#define Y 123
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 800
void MouseSetup(INPUT *buffer)
{
buffer->type = INPUT_MOUSE;
buffer->mi.dx = (0 * (0xFFFF / SCREEN_WIDTH));
buffer->mi.dy = (0 * (0xFFFF / SCREEN_HEIGHT));
buffer->mi.mouseData = 0;
buffer->mi.dwFlags = MOUSEEVENTF_ABSOLUTE;
buffer->mi.time = 0;
buffer->mi.dwExtraInfo = 0;
}
void MouseMoveAbsolute(INPUT *buffer, int x, int y)
{
buffer->mi.dx = (x * (0xFFFF / SCREEN_WIDTH));
buffer->mi.dy = (y * (0xFFFF / SCREEN_HEIGHT));
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE);
SendInput(1, buffer, sizeof(INPUT));
}
void MouseClick(INPUT *buffer)
{
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN);
SendInput(1, buffer, sizeof(INPUT));
Sleep(10);
buffer->mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP);
SendInput(1, buffer, sizeof(INPUT));
}
int main(int argc, char *argv[])
{
INPUT buffer[1];
MouseSetup(&buffer);
MouseMoveAbsolute(&buffer, X, Y);
MouseClick(&buffer);
return 0;
}
You'll need to call MouseSetup() to each INPUT buffer before you use it.
Resources
MSDN - SendInput()
MSDN - INPUT
MSDN - MOUSEINPUT
Here is a solution using Xlib for those who use Linux :
#include <X11/Xlib.h>
#include<stdio.h>
#include<unistd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
void mouseClick(int button)
{
Display *display = XOpenDisplay(NULL);
XEvent event;
if(display == NULL)
{
fprintf(stderr, "Errore nell'apertura del Display !!!\n");
exit(EXIT_FAILURE);
}
memset(&event, 0x00, sizeof(event));
event.type = ButtonPress;
event.xbutton.button = button;
event.xbutton.same_screen = True;
XQueryPointer(display, RootWindow(display, DefaultScreen(display)), &event.xbutton.root, &event.xbutton.window, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
event.xbutton.subwindow = event.xbutton.window;
while(event.xbutton.subwindow)
{
event.xbutton.window = event.xbutton.subwindow;
XQueryPointer(display, event.xbutton.window, &event.xbutton.root, &event.xbutton.subwindow, &event.xbutton.x_root, &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
}
if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");
XFlush(display);
usleep(100000);
event.type = ButtonRelease;
event.xbutton.state = 0x100;
if(XSendEvent(display, PointerWindow, True, 0xfff, &event) == 0) fprintf(stderr, "Error\n");
XFlush(display);
XCloseDisplay(display);
}
int main(int argc, char * argv[]) {
int x , y;
x = atoi(argv[1]);
y = atoi(argv[2]);
Display *display = XOpenDisplay(0);
Window root = DefaultRootWindow(display);
XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
mouseClick(Button1);
XFlush(display);
XCloseDisplay(display);
return 0;
}
Just Build it and then to simulate a click at x ,y do:
$ ./a.out x y
i.e.
$g++ -lX11 sgmousesim2.cpp
$./a.out 123 13
Use SendInput to generate the input you want to simulate. From MSDN documentation:
Synthesizes keystrokes, mouse motions, and button clicks.
I have never did this using C++. Nevertheless, there is a Java class called Robot which is able to produce mouse events. I used this back on Java version 1.4 but it does still work. I tried the example from this Simulate a physical mouse move in Mac OS X. It runs smoothly with Oracle Java 1.6.0_26 on MacOSX Lion. The good about Java is that it is platform independent.
import java.awt.AWTException;
import java.awt.Robot;
public final class MovingMouseDemo
{
public static void main(String[] args) throws AWTException
{
Robot robot = new Robot();
robot.setAutoDelay(5);
robot.setAutoWaitForIdle(true);
//put mouse in the top left of the screen
robot.mouseMove(0, 0);
//wait so that you can see the result
robot.delay(1000);
//put the mouse 200 pixels away from the top
//10 pixels away from the left
robot.mouseMove(200, 10);
robot.delay(1000);
robot.mouseMove(40, 130);
}
}
You can still use JNI to bind it with C++.
I hope it helps
C++ alone can't do this. It has no concept of a "mouse", let alone a "click".
You need some sort of library which talks to your windowing system. For example, QT. Then it's a matter of searching through the API and making the right C++ calls.
Use the mouse_event function.