Défrichage pour la création d'un clavier virtuel

Par où commencer ? Quelle lib utiliser ??

a marqué ce sujet comme résolu.

Bonjour ! Voyez-vous le clavier virtuel de Windows ? Celui-ci !

clavier virtuel de Windows... Pardon je sais pas réduire la taille d'une image avec MarkDown :'(
clavier virtuel de Windows… Pardon je sais pas réduire la taille d’une image avec MarkDown :’(

Bref, je m’interroge beaucoup dessus. C’est un programme… Donc que sa fenêtre passe par dessus les autres même en changeant le focus, je peux me figurer comment ça fonctionne. Par contre, que ce programme puisse envoyer des choses à tous les autres (du texte quoi), et que quand je clique sur une lettre pour écrire ce message le focus reste sur le navigateur, ça ça me fascine ! :O

Je suis en vacances, donc j’ai du temps libre devant moi. Dans ce cas, le meilleur moyen de comprendre comment fonctionnent les deux trucs mentionnés en haut, c’est de recréer ce programme from scratch.
C’est là que j’ai besoin d’aide : Je ne sais pas par où commencer. Je connais le C++ (Qui me semble être le plus adapté des langages que je connais), mais ça a ses limites : simuler une entrée clavier après un clic… Bon je suppose que je vais avoir besoin de Qt pour faire de la gestion d’évènements propres, et que je vais me limiter à 6 lettres pour commencer et comprendre le principe, mais ça s’arrête là. Derrière, comment définir la priorité de mon programme par rapport aux autres, quelles librairies utiliser, je ne sais pas.
ChatGPT me parle de 'Windows API’, mais je crois que c’est pour du C ? Ce qui me priverai de Qt qui serait si utile pour la partie graphique, et aussi de l’aspect orienté objet. Certaines vidéos parlent de Visual C++ dont je ne connais pas les subtilité par rapport au C++ normal. Enfin en scrollant sur Google, je trouve Qt Virtual Keyboard, mais il semble que ce soit pour créer un clavier qui reste cantonné au programme où il est inclut…

Avez-vous des indications pour démarrer ce projet ?

Merci !

Edit

Avant de m’attaquer l’interface graphique, ça me semble plus important de faire fonctionner les différentes fonctions du programme. De fil en aiguille, je suis arrivé à la doc de la fonction SendInput(). Qui fait exactement ce qu’il faut : elle envoie à l’OS l’information qu’il y a eu une entrée clavier, et c’est lui qui gère ! Bon j’aimerai bien savoir comment cette fonction fait ça, mais je ne pense pas encore avoir le niveau pour la communication avec les OS, peut-être programme de l’année prochaine ça.
J’ai fait une petite application rapide, pour vérifier que cette fonction a bien le comportement attendu…

/*
 *  main.cpp
 *
 */

// Headers
#include <iostream>
#include <Windows.h>

int main(int argc, char *argv[]){
    std::cout << "Hello World!" << std::endl;
    INPUT inputs[4] = {};
        inputs[0].type = INPUT_KEYBOARD;
        inputs[0].ki.wVk = VK_LWIN;
        //...
        inputs[1].type = INPUT_KEYBOARD;
        inputs[1].ki.wVk = VK_LWIN;
        inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
        //...
        inputs[2].type = INPUT_KEYBOARD;
        inputs[2].ki.wVk = 'A';
        //...
        inputs[3].type = INPUT_KEYBOARD;
        inputs[3].ki.wVk = 'A';
        inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;


    SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
    return 0;
}

J’ai bien le menu Windows qui s’ouvre ! je suis trop content, j’ai reçu la même excitation que quand on fait son premier "programme" et qu’une console s’ouvre pour afficher "Hello World!" :’D … Me jugez pas. XP

Cependant, la lettre 'A' n’est pas tapée dans la barre de recherche du menu Démarrer. J’ai bien essayé à la classique : J’ai pas besoin d’aller cliquer dessus normalement, juste appuyer sur une lettre (quand le menu est ouvert) suffit à mettre le focus sur la barre de recherche. Quelle peut être la cause de cela ? le délai ? Je ne vois pas de manière, dans la doc, d’imposer un délai entre les appuis de touches, et faire plusieurs appels successifs de SendInput() avec un appel à Sleep() entre chaque me paraît être une pratique très… Sale ?

P.S. : Oui, je sais qu’avec cette méthode je me prive de faire fonctionner le programme sur Linux… Comprendre le fonctionnement sur Windows est une étape, le comprendre pour Linux en sera une autre, puis créer ma fonction 'UtiliserClavier()` qui fera elle-même l’interface entre mon code principal et les fonctions variants selon les OS en sera une dernière à la toute fin. :’D

+0 -0

Hello,

Je pense effectivement que c’est le délai. Windows ne gère pas vraiment les inputs trop rapides pour son interface graphique, et logiquement avec le clavier virtuel ça prend un temps fou avant d’appuyer sur une autre touche.

Et c’est normal que tu ne puisses développer que pour windows : le clavier virtuel, piur toutes les fonctionnalités que tu as notées er qui lui sont fondamentales, est profondément ancré dans l’API windows. C’est à mon avis la seule chose que tu aies à faire, fouiller la doc de WinAPI et t’en servir à fond.

+3 -0

Coucou, Merci Moté ! Je partage mes petites avancées du coup ! D’une part il y avait bien un problème avec le délai, mais partiel : En fait c’est juste que quand j’appuie sur la touche "Windows", le temps que le menu s’affiche… bref un délai de 100ms juste après cette résout le problème, pas besoins de délais ailleurs.
Un autre petit problème que j’ai pu constater, c’est que l’instruction inputs[2].ki.wVk = 'A'; va mener à avoir un 'a' qui s’affiche. Pourquoi ? je ne sais pas. L’instruction inputs[2].ki.wVk = 'a'; va elle donner un 1... En faisant des tests et lisant la doc j'ai compris qu'en fait la fonction SendInputne va pas envoyer un caractère, mais dire 'Eh cette touche a été pressée !' Il est donc nécessaire d'une part de récupérer la dispo du clavier, d'autre part de convertir un caractère en une touche avec la fonctionVkKeyScanEx`. Mais du coup, c’est relou pour les touches '& / 1' et les suivantes… ^^

Petite question au sujet de l’utilisation du forum, certainement à l’adresse de la modération. Je sens que je vais avoir besoin d’aide à plusieurs reprises, sur ce projet. Est-il préférable que je fasse un sujet par question, ou bien que j’utilise celui-ci comme un seul gros sujet sur le projet, que je up à chaque fois que j’ai une question ?? (veut éviter le flood)

Salut,

Lorsque ton clavier communique par USB, il est interprété par une partie de l’OS : les pilotes (drivers). Les drivers connaissent les spécificités matérielles d’un équipement et vont lever des évènements dans l’OS.
Ton clavier virtuel va être un programme écrit à la manière d’un driver, seulement au lieu d’interpréter une communication matérielle, il va interpréter une interaction graphique.

Le focus va être géré par une autre partie du système qui est le gestionnaire de fenêtre (sur Windows il n’y a pas le choix mais sur linux il en existe plusieurs). Donc pour que ton programme reçoive le clic sans prendre le focus, il va falloir interagir avec ce gestionnaire de fenêtre certainement (ou peut être même avec le serveur d’affichage).
Et c’est cette fonctionnalité qui est très spécifique, c’est pas un besoin très récurent, alors je ne pense pas que tu puisses le trouver dans des libs multiplateformes.

En somme, il faut bien que tu travailles avec Windows.h


Visual C++ est l’IDE de microsoft pour C++, ce n’est pas un langage dérivé. C’est juste que puisque c’est microsoft il a quelques fonctionnalités qui aident les devs pour plateforme microsoft.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte