IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Détection des évènements clavier depuis une application console


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2022
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2022
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Détection des évènements clavier depuis une application console
    Bonjour à tous.

    Je cherche un moyen de détecter les actions clavier de l'utilisateur par évènement, dans une application console. Le but est d'avoir une fonction qui est appelée lorsque l'utilisateur appuie sur une touche.
    J'ai en tête pour référence le C# avec son système d'abonnement à des évènements grâce aux déléguées, mais je ne sais pas s'il y a un système équivalant en C++ avec les bibliothèques standard.

    Durant mes recherches, j'ai trouvé plusieurs méthodes pour récupérer des saisies claviers. Mais soit elle ne récupère les actions clavier qu'à un instant T (cin, fonction kbhit et getchar, fonction GetKeyState et GetAsyncKeyState, fonction ReadConsoleInput), soit je ne les ai pas comprise et n'ai pas réussi à les implémenter (Message WM_KEYUP et WM_KEYDOWN, fonction SetWindowsHookExA et procédure de hook).
    Voilà pourquoi je me tourne vers ce forum en espérant que vous puissiez me donner un éclaircissement sur tout ça.

    Ci-dessous, je liste plusieurs liens vers des discussions que j'ai lues pendant mes recherches. Peut-être que l'un de vous pourra mettre le doigt sur quelque chose que j'ai loupé :

    - Utilisation de ReadConsoleInput :
    https://iq.direct/blog/325-how-to-re...nsole-app.html

    - Utilisation de SetWindowsHookExA et procédure de hook :
    https://eticweb.info/tutoriels-c-2/e...avier-c-win32/

    - Utilisation de SetWindowsHookExA par microsoft:
    https://docs.microsoft.com/fr-fr/win...sg/using-hooks

    - ReadConsoleInput, ReadKeyState, GetAsyncKeyState et procédure de hook
    https://stackoverflow.com/questions/...eyboard-events

    - GetAsyncKeyState et Message WM_KEYUP et WM_KEYDOWN :
    https://www.developpez.net/forums/d1...ement-clavier/

  2. #2
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 360
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 360
    Points : 20 378
    Points
    20 378
    Par défaut
    pour utiliser GetAsyncKeyState c'est simple il suffit de faire une boucle et détecter donc les touches claviers enfoncées,voir l'utilisation dans le MSDN.
    Citation Envoyé par ardra Voir le message
    J'ai en tête pour référence le C# avec son système d'abonnement à des évènements grâce aux déléguées, mais je ne sais pas s'il y a un système équivalant en C++ avec les bibliothèques standard.
    l'équivalent des delegates en C# ce sont les foncteurs en C/C++ bref les pointeurs de fonction.
    Si on veut gérer WM_KEYDOWN il me semble qu'il faut créer une classe de fenêtre,l'initialiser avec un pointeur de fonction et une "boucle de message".

  3. #3
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2022
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2022
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Bonjour Mat.M et merci de ta réponse.

    Citation Envoyé par Mat.M Voir le message
    Si on veut gérer WM_KEYDOWN il me semble qu'il faut créer une classe de fenêtre,l'initialiser avec un pointeur de fonction et une "boucle de message".
    Je suis en train d'étudier cette solution en suivant ce tutoriel : https://docs.microsoft.com/fr-fr/win...am-for-windows
    Malheureusement, cette approche me paraît un peu compliquée et nécessite de créer une fenêtre Windows. Or, je souhaite pouvoir détecter les évènements depuis une simple application console.
    N'y a-t-il pas d'autres solutions ? Le top pour moi serait de trouver une fonction permettant de m'abonner aux évènements clavier, en prenant en paramètre le pointeur sur ma fonction de routine d'évènement. Voici un exemple pour illustrer ce que je recherche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    #include <iostream>
    #include ... //Autres include
     
    void monEventHandler (int codeKey)
    {
       //ma routine d'évènement
       //Exemple...
       std::cout << "La touche " << codeKey << " à été pressé" << std::endl;
    }
     
    int main()
    {
       //Abonnement à l'évènement
       FonctionAbonnementEventKeyboard(&monEventHandler);
     
       //Boucle pour éviter la fermeture du programme
       while(1);
     
       return 0;
    }

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    En fait, je me pose deux questions, dont la réponse à l'une va sans doute fortement influencer l'intérêt de la deuxième.

    La première te conseille au premier plan: es tu réellement assez à l'aise avec le C++ que pour "abandonner" la console en t'attaquant à des programmes plus complexes, susceptibles d'utiliser ce que l'on appelle en générale une "interface graphique"

    Car l'idée générale est que l'on peut vraiment apprendre énormément du C++ en ne faisant que des "projets jetables": ce sont des projets qui ne sont généralement pas destinés à survivre beaucoup plus longtemps que quelques semaines à quelques mois, et dont le but est "de se faire la main" en restant malgré tout "relativement simples".

    Le fait que tu aies choisi de suivre un tutoriel dédié à win32 semble indiquer que tu as sans doute "loupé pas mal de choses" et qu'il pourrait être utile de réfléchir un peu plus à ce que tu veux faire, là, maintenant, tout de suite, histoire de continuer à t'améliorer sans te perdre dans les méandres d'une bibliothèque qui n'est vraiment pas faite ni pour les débutants ni pour la portabilité.

    La deuxième question n'aura donc du sens que si tu te sens près à "franchir le pas" consistant à créer un programme "graphique" (comprend: qui utilise d'une manière ou d'une autre une interface graphique pour dialoguer avec l'utilisateur): ne serait-il pas plus utile et enrichissant pour toi de t'intéresser à des bibliothèques qui te permettent de "t'abstraire" des différences liées aux différents systèmes d'exploitation pour créer ton interface graphique

    Cela te permettrait de faire d'une pierre deux coups, en te permettant de donner un look "plus intéressant" à ton programme tout en te permettant bien souvent de passer le cap de la portabilité, la plupart des bibliothèques auxquelles je pense permettant de créer des programmes qui pourront compiler et s'exécuter aussi bien sous windows, sous mac ou sous linux.

    Tu pourrais, par exemple, te tourner vers l'utilisation de Qt ou de la SFML pour la création de tes applications "graphiques". Cela pourrait te simplifier énormément la vie, même si cela impliquera forcément qu'il te faille "un certain temps" pour prendre ces bibliothèques en main

    Mais de manière générale, tu aura beaucoup plus de plaisir et tu tirera beaucoup plus de profit (en termes d'apprentissage du C++) à utiliser ces bibliothèque que la bibliothèque win32
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2022
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2022
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Salut koala01.

    Pour répondre à ta question, non je ne suis pas spécialement à l'aise avec le C++ pour l'instant. Ayant déjà fait du C et du C#, les bases en C++ sont assez rapides à maitriser, mais il me reste à apprendre toutes les possibilités des bibliothèques standard et des bibliothèques un peu plus avancé.

    Ensuite, comme décrit dans mes postes précédants, je cherche à détecter les évènements clavier depuis une application console. Donc, pour l'instant, je ne suis pas intéressé à faire une application graphique. Le but à la fin serait de faire une mini-jeux console, comme par exemple un snake.
    Je me suis intéressé à ce tutoriel (https://docs.microsoft.com/fr-fr/win...am-for-windows) car il parle à un moment de gestion d'évènement clavier. Je souhaitais voir s'il était possible de transposer ça à une application console.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pour une appli console, c'est bien ReadConsoleInput() qu'il va te falloir utiliser. Et probablement SetConsoleMode() aussi pour désactiver ENABLE_LINE_INPUT.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Candidat au Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Mai 2022
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Mai 2022
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Pour une appli console, c'est bien ReadConsoleInput() qu'il va te falloir utiliser. Et probablement SetConsoleMode() aussi pour désactiver ENABLE_LINE_INPUT.
    J'ai déjà étudié cette option. Avec GetNumberOfConsoleInputEvents, il y a bien un début de solution qui ce profil, mais le problème, c'est que ce sera de la scrutation. Il me faudra une boucle qui vient regarder tous les X temps s'il y a une saisie de l'utilisateur. Or, je cherche plutôt une solution en événementielle, du type que j'ai décrit dans un de mes précédents poste :
    Citation Envoyé par ardra Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    #include <iostream>
    #include ... //Autres include
     
    void monEventHandler (int codeKey)
    {
       //ma routine d'évènement
       //Exemple...
       std::cout << "La touche " << codeKey << " à été pressé" << std::endl;
    }
     
    int main()
    {
       //Abonnement à l'évènement
       FonctionAbonnementEventKeyboard(&monEventHandler);
     
       //Boucle pour éviter la fermeture du programme
       while(1);
     
       return 0;
    }
    Je ne sais pas si une telle solution existe mais cela me paraîtrait bizarre que les programmes PC actuelles aient chacun une routine qui vient scruter continuellement s'il y a un nouveau caractère qui a été tapé.

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Il va falloir remplacer le while(1) par une fonction qui appelle ReadConsoleInput() etc. en boucle, et appelle tes callbacks en conséquence.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 0
    Dernier message: 28/12/2010, 19h36
  2. [WD15] Gestion des événements clavier dans une fenêtre.
    Par dvdbly dans le forum WinDev
    Réponses: 3
    Dernier message: 20/09/2010, 08h58
  3. Réponses: 3
    Dernier message: 06/03/2009, 21h24
  4. Réponses: 1
    Dernier message: 28/03/2008, 22h34
  5. Réponses: 7
    Dernier message: 19/04/2007, 13h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo