Pour gérer les interactions de la souris dans une application console sous Windows en C++, on utilise la fonction ReadConsoleInput de l'API Windows. Cette approche est analogue à la capture des événements clavier.
Le fichier d'en-tête nécessaire est :
#include <windows.h>
Les événements de la souris sont stockés dans une variable de type INPUT_RECORD. Lorsqu'un événement de souris est détecté, ses détails sont accessbiles via la structure MOUSE_EVENT_RECORD, dont la définition est la suivante :
typedef struct _MOUSE_EVENT_RECORD {
COORD positionSouris; // Position actuelle de la souris
DWORD etatBouton; // État des boutons de la souris
DWORD etatToucheControle; // État des touches de contrôle du clavier
DWORD evenementType; // Type d'événement
} MOUSE_EVENT_RECORD;
Ces informations se trouvent généralement dans variableInputRecord.Event.MouseEvent.membre.
La structure COORD conteint les coordonnées X et Y. Le champ etatBouton indique quel bouton est activé, avec les valeurs possibles suivantes :
| Code d'état du bouton (etatBouton) | Description |
|---|---|
| FROM_LEFT_1ST_BUTTON_PRESSED | Bouton le plus à gauche |
| FROM_LEFT_2ND_BUTTON_PRESSED | Deuxième bouton en partant de la gauche |
| FROM_LEFT_3RD_BUTTON_PRESSED | Troisième bouton en partant de la gauche |
| FROM_LEFT_4TH_BUTTON_PRESSED | Quatrième bouton en partant de la gauche |
| RIGHTMOST_BUTTON_PRESSED | Bouton le plus à droite |
Le champ evenementType spécifie l'action de la souris :
| Code d'événement (evenementType) | Description |
|---|---|
| DOUBLE_CLICK | Double-clic |
| MOUSE_MOVED | Mouvement de la souris |
| MOUSE_WHEELED | Défilement de la molette (uniquement pour Windows 2000/XP) |
Pour initialiser les périphériques d'entrée et de sortie, on obtient les handles standards :
HANDLE sortieConsole = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE entreeConsole = GetStdHandle(STD_INPUT_HANDLE);
Voici un exemple simple qui affiche la position lors d'un clic gauche et termine sur un double-clic :
#include <iostream>
#include <windows.h>
int main() {
HANDLE hSortie = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hEntree = GetStdHandle(STD_INPUT_HANDLE);
INPUT_RECORD enregistrement;
DWORD nombreLus;
while (true) {
ReadConsoleInput(hEntree, &enregistrement, 1, &nombreLus);
if (enregistrement.EventType == MOUSE_EVENT) {
if (enregistrement.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) {
if (enregistrement.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) {
break;
} else {
COORD pos = enregistrement.Event.MouseEvent.dwMousePosition;
std::cout << "Position: " << pos.X << ", " << pos.Y << std::endl;
}
}
}
}
CloseHandle(hSortie);
CloseHandle(hEntree);
return 0;
}
Un autre exemple plus avancé affiche la position en temps réel et remplit des caractères selon le bouton cliqué :
#include <windows.h>
#include <cstdio>
int main() {
HANDLE hSortie = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hEntree = GetStdHandle(STD_INPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO infoTampon;
INPUT_RECORD evenement;
DWORD quantite;
COORD position, origine = {0, 0};
printf("[Position] X: %2lu Y: %2lu\n", 0, 0);
while (true) {
ReadConsoleInput(hEntree, &evenement, 1, &quantite);
if (evenement.EventType == MOUSE_EVENT) {
if (evenement.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED &&
evenement.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK) {
break;
}
position = evenement.Event.MouseEvent.dwMousePosition;
GetConsoleScreenBufferInfo(hSortie, &infoTampon);
SetConsoleCursorPosition(hSortie, origine);
printf("[Position] X: %2lu Y: %2lu", position.X, position.Y);
SetConsoleCursorPosition(hSortie, infoTampon.dwCursorPosition);
switch (evenement.Event.MouseEvent.dwButtonState) {
case FROM_LEFT_1ST_BUTTON_PRESSED:
FillConsoleOutputCharacter(hSortie, 'A', 1, position, &quantite);
break;
case RIGHTMOST_BUTTON_PRESSED:
FillConsoleOutputCharacter(hSortie, 'a', 1, position, &quantite);
break;
default:
break;
}
}
}
CloseHandle(hSortie);
CloseHandle(hEntree);
return 0;
}