SendInput () ne correspond pas à une pression manuelle sur une touche du clavier en C ++?

Je voulais écrire un code c ++ à émuler en appuyant sur une touche du clavier “A”:

// Set up a generic keyboard event. ip.type = INPUT_KEYBOARD; ip.ki.wScan = 0; // hardware scan code for key ip.ki.time = 0; ip.ki.dwExtraInfo = 0; // Press the "..." key ip.ki.wVk = code; // virtual-key code for the "a" key ip.ki.dwFlags = 0; // 0 for key press SendInput(1, &ip, sizeof(INPUT)); // Release the "..." key ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release SendInput(1, &ip, sizeof(INPUT)); 

Cela fonctionne bien lorsque je lance un autre programme et que j’attends que mon programme soit exécuté, on clique sur le “A” et le premier programme y réagit. Mais j’ai trouvé que, dans l’autre application, mon action était empêchée (je peux appuyer manuellement sur la touche “A” du clavier, mais mon programme ne provoque aucune action).

Alors, que puis-je faire pour que le fait d’appuyer sur “A” depuis le programme soit plus identique que d’appuyer manuellement sur “A” (pour que le second programme ne reconnaisse pas qu’il a été appelé depuis programme)?

Je n’ai pas le code source du second programme et je ne sais pas comment il reconnaît que “A” n’a pas été pressé manuellement.

Je suis sûr que la fenêtre que je veux réagir à mon code est au premier plan, recevoir et bloquer ma clé (pour qu’il puisse décider que cet événement ne vient pas de l’utilisateur mais du programme).

Vous pouvez également utiliser SendInput () pour envoyer des codes de scan matériel (par opposition aux codes de scan virtuels, que DirectInput peut ignorer). C’est mal documenté, mais SendInput () peut en effet contourner DirectInput. La solution d’Eric n’a pas fonctionné parce qu’il a défini le code d’parsing du matériel, mais a fini par utiliser un code d’parsing virtuel (en définissant dwFlags sur 0 et sur wVk sur une valeur non nulle).

Pour faire une pression sur une touche, vous souhaitez définir:

 ip.ki.dwFlags = KEYEVENTF_SCANCODE; 

Et pour faire une libération de clé, définissez:

 ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; 

Un exemple de travail complet est ci-dessous et il imprime la lettre “a”. Vous pouvez trouver d’autres codes de balayage ici .

 #define WINVER 0x0500 #include  using namespace std; int main() { //Structure for the keyboard event INPUT ip; Sleep(5000); //Set up the INPUT structure ip.type = INPUT_KEYBOARD; ip.ki.time = 0; ip.ki.wVk = 0; //We're doing scan codes instead ip.ki.dwExtraInfo = 0; //This let's you do a hardware scan instead of a virtual keypress ip.ki.dwFlags = KEYEVENTF_SCANCODE; ip.ki.wScan = 0x1E; //Set a unicode character to use (A) //Send the press SendInput(1, &ip, sizeof(INPUT)); //Prepare a keyup event ip.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); return 0; } 

Remarque: Vous pouvez combiner des appuis sur les touches (comme Maj + a pour A) en transmettant à SendInput () un tableau de structures INPUT.

Vous devez souvent définir le code d’parsing:

 // Set up a generic keyboard event. ip.type = INPUT_KEYBOARD; ip.ki.wScan = MapVirtualKey(code, MAPVK_VK_TO_VSC); // hardware scan code for key ip.ki.time = 0; ip.ki.dwExtraInfo = 0; // Press the "..." key ip.ki.wVk = code; // virtual-key code for the "a" key ip.ki.dwFlags = 0; // 0 for key press SendInput(1, &ip, sizeof(INPUT)); 

Et la construction d’un tableau, comme le suggère Inspectable, est également certainement la voie à suivre.

Si vous cherchez à créer un robot de jeu, avez-vous consulté le programme AutoHotKey? http://www.autohotkey.com/

Il offre un langage de script qui vous permet de réaliser une grande partie des tâches de la création de “bot”. C’est plus simple que d’essayer de tout faire en C ++.

(Cela a certainement joué Farmville pour moi, quand toute ma famille m’a fait pression pour créer un compte)