21

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?

0

6 Answers 6

46

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

6
  • 1
    Better use x * 0xFFFF / SCREEN_WIDTH + 1 for pixel-perfect coordinate normalization. (For all values of SCREEN_WIDTH < (0xFFFF / 2) and x <= SCREEN_WIDTH). Your formula can be tens of pixels off for common screen resolutions. Commented Sep 17, 2013 at 14:17
  • This is required - otherwise you will have worsening cursor positioning accuracy from left-to-right and top-to-bottom.
    – Ani
    Commented Dec 5, 2013 at 23:15
  • MouseSetup() to each INPUT means each variable of type INPUT... I was confused - at the first sight I thought you have to call it before every mouseinput (which made no sense...).
    – jave.web
    Commented Nov 21, 2014 at 16:44
  • how to retrieve SCREEN_WIDTH and SCREEN_HEIGHT to make MouseMoveAbsolute() display size (resolution) independent? Commented Dec 7, 2016 at 20:23
  • 1
    " (x * (0xFFFF / SCREEN_WIDTH));" result in very huge values.Is it supposed to be like that?
    – Michael IV
    Commented Sep 15, 2017 at 16:37
27

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
2
  • 2
    That's quite correct for X11, but the question did get clarified to ask for a Windows solution.
    – Flexo
    Commented Jan 9, 2012 at 17:09
  • 8
    Just noticed it :) . maybe it will help those who come looking for a Linux specific solution.
    – Aman
    Commented Jan 9, 2012 at 17:13
3

Use SendInput to generate the input you want to simulate. From MSDN documentation:

Synthesizes keystrokes, mouse motions, and button clicks.

1

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

0

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.

0

Use the mouse_event function.

3
  • 2
    If you read the documentation, it says "Note This function has been superseded. Use SendInput instead." Commented Sep 21, 2011 at 23:36
  • 1
    It works anyway in Win2k and WinXP. I've checked this. I don't know about support in W7, but I assume that mouse_event will work too because there are many legacy code using it.Also syntax of this function is more obvious than syntax of SendInput. Commented Sep 22, 2011 at 0:39
  • Whether something works or not is not important. A lot of things work fine. once, or when your testing, or on 1 machine. Whats important is that you were told by the vendor not to use it, and you ignore them. You will not PASS certification on that vendors platform. And if you dont need certification, you will most likely just piss off customers by selling them broken crap. Its deprecated for a reason. DO NOT USE IT. Could be there is a 1 in 10000 chance that you kill someone. You dont know. so dont use it.
    – Dan
    Commented May 1, 2019 at 22:39

Not the answer you're looking for? Browse other questions tagged or ask your own question.