dimanche 10 octobre 2010

Simuler un keyPress multimédia avec C# et/ou C++

Simuler un appui touche dans un programme est des fois nécessaire pour permettre a 2 programmes ou un programme et le système d'exploration de communiquer.

C++
En C++ c'est facile, on a besoin de la méthode keybd_event(keyCode,0 , 0/2, 0de la bibliothèque <windows.h> en ce qui concerne Windows et <X11/Xlib.h> pour Linux:

VOID WINAPI keybd_event(
  __in  BYTE bVk, // le code de la touche
  __in  BYTE bScan,
  __in  DWORD dwFlags, // 0 pour bouton appuyé et 2 pour relâché
  __in  ULONG_PTR dwExtraInfo
);
Remarque: Cette fonction a été remplacée. Utilisez SendInput a sa place.
Pour les codes des touches voici le tableau complet : Tableau.
Voici un exemple:

/*
Créateur: S. Bourouis
blog: esaemi.blogger.com
Licence: GNU
*/
#include <iostream>
#include <stdlib.h>
#include <windows.h> // Windows (A supprimer sous linux)
#include <x11/xlib.h> // Linux (A supprimer sous windows)
#include <string>

using namespace std;

int simulateKeyPress(byte keyCode) {
    keybd_event(keyCode, 0, 0, 0); // Bouton appuyé
    keybd_event(keyCode, 0, 2, 0); // Bouton relâché
}

int main(int argc, char** argv) {

    try {
        string keyToSimulate = argv[1]; // On récupère le bouton a simuler
        
        if (strcmp(argv[1], "")) {
            std::cout << "" << std::endl;
            std::cout << "  Sending key : \"" + keyToSimulate + "\"" << std::endl;
            std::cout << "" << std::endl;
        }

        if (!strcmp(argv[1], "play")) {
            simulateKeyPress(0xB3);
        } else if (!strcmp(argv[1], "stop")) {
            simulateKeyPress(0xB2);
        } else if (!strcmp(argv[1], "next")) {
            simulateKeyPress(0xB0);
        } else if (!strcmp(argv[1], "prev")) {
            simulateKeyPress(0xB1);
        } else if (!strcmp(argv[1], "volup")) {
            simulateKeyPress(0xAF);
        } else if (!strcmp(argv[1], "voldown")) {
            simulateKeyPress(0xAE);
        } else if (!strcmp(argv[1], "mute")) {
            simulateKeyPress(0xAD);
        }

    } catch (exception exp) {
        std::cout << "" << std::endl;
        std::cout << "  Must provide key to dispatch :" << std::endl;
        std::cout << "  play | stop | next | prev | volup | voldown | mute" << std::endl;
        std::cout << "" << std::endl;
    }

    return (EXIT_SUCCESS);
}


Compilez puis utilisez cette fonction avec la console: simuler_touche.exe play

C#
En C# la méthode c'est la suivante:
SendKeys.Send("Code");
SendKeys.Send("{Key}");
Pour les codes des touches voici le tableau complet : Tableau.
Le probleme maintenant c'est que C# ne nous permet pas de simuler toutes les touches comme le fait C++, surtout les touches multimédia, alors soit on utilise le .exe qu'on a et on l'appelle depuis csharp comme suit:
Process cmd = new Process();
cmd.StartInfo.FileName = "simuler_touche.exe play";
cmd.Start();
cmd.Kill();

Soit on utilise la méthode keybd_event dans notre programme C#


C#/C++
/*
Créateur: S. Bourouis
blog: esaemi.blogger.com
Licence: GNU
*/
using System;
using System.Runtime.InteropServices;

namespace Programme // A changer!
{
    class SimulateKeyPress
    {
        // Utiliser DllImport pour importer la methode keybd_event
        // depuis user32.dll qui est présent par defaut dans votre systeme
        [DllImport("user32.dll",
                EntryPoint = "keybd_event",
                CharSet = CharSet.Auto,
                ExactSpelling = true)]

        public static extern void keybd_event(byte vk,
                 byte scan,
                 int flags,
                 int extrainfo);
        
        public static void Send(byte keyCode)
        {
            keybd_event(keyCode, 0, 0, 0); // Bouton appuyé
            keybd_event(keyCode, 0, 2, 0); // Bouton relâché
        }
    }
}

Quand on a besoin de simuler n'importe quel touche on ecrit:

SimulateKeyPress.Send(0xB3); // Play
SimulateKeyPress.Send(0xB2); // Stop

Le code de la touche est celui qui est utilisé en C++.


Pour plus d'informations laissez un commentaire.

1 commentaire:

  1. Merci pour le tutoriel =) Super boulot ! très clair et précis !!

    RépondreSupprimer