Émuler un mouvement de souris (Windows/JAVA)

Ceux qui programment sur Windows depuis un certain temps savent qu’il est simple d’envoyer des messages d’une application à l’autre et ainsi pouvoir émuler des événements. Par contre, il existe nombre de situations où l’émulation ne suffit plus, mais il faut réellement que la souris soit déplacée ou une touche du clavier pressée.

Exemple d’application

  • Un programme tel VNC pour administrer un ordinateur à distance
  • Un programme qui teste les interfaces graphiques
  • Un programme qui aide l’utilisateur pour l’amener à devenir plus autonome

Comment faire

Pour la Win32API, il y a une fonction qui s’occupe d’émuler des événements matériel. C’est la fonction « SendInput » qui permet de déplacer la souris, cliquer/relâcher n’importe quel bouton de la souris et appuyer/relâcher n’importe quelle touche même les spéciales (flèches, tab, ctrl, …) .

Pour Java, il y a une classe qui est spécialisée dans ces fonctionnalités en plus de permettre d’obtenir un screenshot de l’écran actuel. Donc sous Java, faire un VNC est extrêment simple puisqu’il ne reste plus que la composante réseau à faire. Cette classe est faite spécifiquement dans le but de faire des tests ou démos. Elle s’appelle « java.awt.Robot »

Windows C++

Voici donc un début de code qui permet de placer la souris à un endroit absolu ou de manière relative à son ancienne position (telle une vrai souris).

#include <windows.h> 

void DeplacerSouris(int x, int y, bool absolue) {
INPUT monInput;

// Remplir tous les champs de 0 par defaut
for (int i=0; i<sizeof(monInput); i++)
((char *) &monInput)[i] = 0;

// Mettre les configurations dans monInput
// http://msdn2.microsoft.com/en-us/library/ms646270(VS.85).aspx
// http://msdn2.microsoft.com/en-us/library/ms646273(VS.85).aspx
monInput.type = INPUT_MOUSE;    // Evenement de souris
monInput.mi.dx = x;    // Position
monInput.mi.dy = y; // Position
monInput.mi.dwFlags = MOUSEEVENTF_MOVE;    // Dire que c’est un mouvement de souris
if (absolue) monInput.mi.dwFlags |= MOUSEEVENTF_ABSOLUTE; // en position absolue

// Envoyer la commande
// http://msdn2.microsoft.com/en-us/library/ms646310(VS.85).aspx
SendInput(1, &monInput, sizeof(monInput));
}

int main() {

// Deplacer la souris a la position 0, 0
DeplacerSouris(0,0, true);

// Deplacer la souris d’un delta de 5, 5 pour faire une diagonale
for (int i=0; i<100; i++) {
Sleep(100);    // 100 ms
DeplacerSouris(5, 5, false);
}

return 0;
}

JAVA

Sous Java, la méthode est plus simple puisqu’il suffit d’appeler des fonctions déjà existantes dans la classe Robot d’AWT.

La seule différence avec le code sous Windows est que la classe Robot ne permet pas de faire des mouvements relatifs. Il est donc un peu comme le « SetCursorPos » de Windows (http://msdn2.microsoft.com/en-us/library/ms648394(VS.85).aspx)

public class Control {
public static void main(String[] args) {
try {
// Creer le robot
// http://java.sun.com/javase/6/docs/api/java/awt/Robot.html
java.awt.Robot monRobot = new java.awt.Robot(); 

// Deplacer la souris d’un delta de 5, 5 pour faire une diagonale
for (int i=0; i<500; i+=5) {
monRobot.delay(100);    // 100 ms
monRobot.mouseMove(i, i);
}
} catch (Exception e) {
System.out.println(« [ERROR] Robot:  » + e.getMessage());
}
}

}