Partage
  • Partager sur Facebook
  • Partager sur Twitter

Utiliser variable pour VirtualKey dans API

    5 septembre 2018 à 11:05:49

    Bonjour,

    Depuis mon thread principal, je créé un thread secondaire où "une macro" s’exécute en boucle.

    Thread Principal :

    std::stringstream  toucheecoutee("0x51");
    std::stringstream  toucheenvoye("0x41");
    std::thread t1(IfAPressSendB, toucheecoutee, toucheenvoye);
    t1.join();

    Thread Secondaire :

    void IfAPressSendB(stringstream KeyListened, stringstream  KeySended)
    {
    	unsigned int ListenedHexVK;
    	KeyListened << std::hex << "fffefffe";
    	KeyListened >> ListenedHexVK;
    
    	unsigned int SendedHexVK;
    	KeySended << std::hex << "fffefffe";
    	KeySended >> SendedHexVK;
    
    	while(1)
    	{ 
    	if (GetAsyncKeyState(ListenedHexVK))
    	{
    		INPUT ip;
    
    		ip.type = INPUT_KEYBOARD;
    		ip.ki.wScan = 0;
    		ip.ki.time = 0;
    		ip.ki.dwExtraInfo = 0;
    
    		ip.ki.wVk = SendedHexVK; // Hex code for 'A'
    		ip.ki.dwFlags = 0; //Press the key down ?
    		SendInput(1, &ip, sizeof(INPUT)); //Use function
    
    		Sleep(50); //Sleep so it doesn't spam the key press
    
    		ip.ki.dwFlags = KEYEVENTF_KEYUP; //Release the key
    		SendInput(1, &ip, sizeof(INPUT)); //Use function
    	}
    	}
    }

    Au début, je convertis mes variables string (non utilisable en string puisque l'API attend un "int") en unsigned int, puis je les utilise en tant que tel. Voici les messages d'erreurs du compilateur :

    1>------ Début de la génération : Projet : ProjetMacroR6S, Configuration : Debug Win32 ------
    1>ProjetMacroR6S.cpp
    1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\memory(2539): error C2664: 'std::tuple<void (__cdecl *)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>,std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>>::tuple(std::tuple<void (__cdecl *)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>,std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>> &&)' : impossible de convertir l'argument 1 de '_Ty' en 'std::allocator_arg_t'
    1>        with
    1>        [
    1>            _Ty=void (__cdecl &)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void))
    1>        ]
    1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\memory(2538): note: Aucun constructeur n'a pu prendre le type de source, ou la résolution de la surcharge du constructeur était ambiguë
    1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\thread(46): note: voir la référence à l'instanciation de la fonction modèle 'std::unique_ptr<std::tuple<void (__cdecl *)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>,std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>>,std::default_delete<_Ty>> std::make_unique<std::tuple<void (__cdecl *)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>,std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>>,void(__cdecl &)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::stringstream&,std::stringstream&,0>(void (__cdecl &)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::stringstream &,std::stringstream &)' en cours de compilation
    1>        with
    1>        [
    1>            _Ty=std::tuple<void (__cdecl *)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>,std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>>>
    1>        ]
    1>c:\users\dridri\desktop\c++vsr6s\projet macro r6s\projetmacror6s\projetmacror6s.cpp(53): note: voir la référence à l'instanciation de la fonction modèle 'std::thread::thread<void(__cdecl &)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void)),std::stringstream&,std::stringstream&,void>(_Fn,std::stringstream &,std::stringstream &)' en cours de compilation
    1>        with
    1>        [
    1>            _Fn=void (__cdecl &)(std::stringstream (__cdecl *)(void),std::stringstream (__cdecl *)(void))
    1>        ]
    1>Génération du projet "ProjetMacroR6S.vcxproj" terminée -- ÉCHEC.
    ========== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========

    J'ai l'impression que le problème vient du multithread ! PS : Je tiens à préciser que si je ne passe pas les VK comme attribut cela fonctionne ! Donc dans le main :

    std::thread t1(IfAPressSendB);

     et le thread secondaire :

    void IfAPressSendB(stringstream KeyListened, stringstream  KeySended)
    {
    	while(1)
    	{ 
    	if (GetAsyncKeyState(0x51))
    	{
    		INPUT ip;
    
    		ip.type = INPUT_KEYBOARD;
    		ip.ki.wScan = 0;
    		ip.ki.time = 0;
    		ip.ki.dwExtraInfo = 0;
    
    		ip.ki.wVk = 0x41; // Hex code for 'A'
    		ip.ki.dwFlags = 0; //Press the key down ?
    		SendInput(1, &ip, sizeof(INPUT)); //Use function
    
    		Sleep(50); //Sleep so it doesn't spam the key press
    
    		ip.ki.dwFlags = KEYEVENTF_KEYUP; //Release the key
    		SendInput(1, &ip, sizeof(INPUT)); //Use function
    	}
    	}
    }

     Là, ça fonctionne parfaitement. Mais mon but c'est de créer une fonction réutilisable alors... Quelqu'un a une idée ? Merci :)

    • Partager sur Facebook
    • Partager sur Twitter
      5 septembre 2018 à 20:14:05

      Votre code "réutilisable" est une horreur.

      Arrêtez de faire des choses sans aucun sens avec des "std::stringstream".

      C'est un flux de caractère, pas un caractère.

      Vous utilisez l'API Win32, qui est une API C, donc utilisez des types C compatibles.

      Une attente avec une boucle infinie, c'est caca.

      C'est quoi votre vrai besoin initial ? (un bot ?)

      Le compilateur vous engueule parce que vous passez "std::thread" des types d'objet non-copiable, et il y a de très très bonne raison pour que des "std::stringstream" soit non-copiable. Utilisez des "int", c'est le type natif de l'API que vous utilisez (même plutôt les constantes "VK_" définies, directement ou indirectement, dans windows.h).

      >J'ai l'impression que le problème vient du multithread !

      Non, vous faites complètement nimportnawak avec des "std::stringstream".

      >Je tiens à préciser que si je ne passe pas les VK comme attribut cela fonctionne !

      Parce que c'est ce qu'il faut faire.

      >Là, ça fonctionne parfaitement.

      Si avoir une pile d'appel de travers, que l'accès aux paramètres donnera au mieux un plantage, mais plus vraisemblablement des valeurs complètement aléatoire, etc.., " n'est pas un problème, alors ça fonctionne parfaitement, LOL.

      >Mais mon but c'est de créer une fonction réutilisable

      Passez des int, c'est parfaitement copiable et c'est bien plus clair avec les constantes "VK_".

      Mais une boucle active, avec des sleeps, qui fait des choses dans la pile de messages Windows de l'application, sans processus d'arrêt, etc..., c'est CACA.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        5 septembre 2018 à 21:25:46

        Salut bacelar,

        Je tiens d'abord à vous remercier pour votre réponse et vos instructions :) Wow, vous ne mâchez pas vos mots ! Je fais beaucoup d'erreurs car je suis un débutant, il y a quelques semaines je ne connaissais pas le C++ et j'ai pris connaissance du multithread que ce matin en cherchant partout. Alors le fond est totalement vrai : je fais de la merde de débutant puisque c'est en faisant des erreurs que l'on progresse. Mais pensez aux petits débutants et essayez, s'il vous plait, de faire attention à la forme et preuve de pédagogie, ce n'est jamais agréable de se faire rabaisser de la sorte ;-)

        Sinon entre temps, j'ai eu l'idée d'isoler le problème. Je me suis dis soit ça vient du multithread, soit de mon utilisation de variables dans l'API (en fait ça venait des deux). Je savais que l'API ne fonctionnait effectivement qu'avec du INT (vu sur microsoft.com) mais j'ai découvert que je n'avais pas BESOIN de mettre de l’hexadécimal ! En fait c'est ça, qui m'a perturbé ! L'API me demandait du INT mais les utilisations c'était du HEX sur microsoft.com. Comment mettre du HEX dans du INT en c++ ? C'est ça qui m'a perturbé ! En convertissant la valeur HEX en decimal et en la stockant dans du INT j'ai vu que ça fonctionnait quand même, alors que je pensais que l'API ne saurait pas traité un format (du décimal) qu'elle n'attendait pas (selon l'explication). Bon déjà 1 problème réglé !

        Ensuite, j'ai donc essayé de passer en paramètre donc 2 variables contenant mes virtualkey(en décimal dans du INT) via le thread principal mais ça ne fonctionnait pas. J'ai cherché pourquoi : il semblerait que l'on ne peut passer en fait que 1 paramètre ! grrr ! Effectivement, si je ne passe que 1 paramètre, plus d'erreur. Alors il faut que je crée une classe, que je crée un objet avec mes valeurs dedans et que j'envoie cette objet en paramètre. C'est bien ça ?

        "Mais une boucle active, avec des sleeps, qui fait des choses dans la pile de messages Windows de l'application, sans processus d'arrêt, etc..., c'est CACA." En fait, c'est pas un bot dans le sens un programme qui fait des actions automatisées sans qu'on le surveille, j'essaye de faire des "macros" ! En gros, quand j'appuie sur une touche d'autres s'activent ou se désactivent. C'est une grosse partie de mon programme de débutant. Du coup, pendant tout le temps où mon programme est actif, plusieurs touchent seront surveillées et si l'une d'entre elle est pressée (ou plusieurs en même temps) alors l'émulation de touches commencera. Si je ne fais pas de boucle infinie dans un autre thread, comment faire pour que ces fonctions s’exécutent constamment ? Le sleep je l'ai mis pour ne pas surcharger le processeur, et le processus d'arrêt c'est la fermeture de mon appli non ? Oulàlà je vais me faire engueuler lol Et dites vous bien que j'ai disons 4 ou 5 touches à surveiller et les 2 boutons de souris ! Imaginez vous bien, j'aurai eu 7 threads de la sorte ! ahahha Une bonne tonne de CACA ! Maintenant que vous savez le but final du programme si vous avez une idée moins CACA je suis preneur !

        • Partager sur Facebook
        • Partager sur Twitter
          6 septembre 2018 à 12:15:04

          > j'ai eu l'idée d'isoler le problème.

          Bon reflex.

          Mais la mise en œuvre est assez approximative.

          Vous faites du partitionnement d'espace de problème dans un espace que vous ne connaissez pas, vous allez vous planter.

          Vous grillez bien trop vite les étapes.

          Faites de la dichotomie de problème, et partez de codes simples et déjà opérationnels.

          Le multi-threading est une chose bien trop complexe à aborder sans être déjà très à laisse avec les bases.

          En plus, pour ce que vous avez à faire, ou du moins ce que j'en ai compris, n'a absolument pas besoin de faire du multi-threading. Je pense que le "hooking" des évènements claviers et souris serait bien plus propre. Mais comme c'est une API C, c'est toujours du Win32, vous aurez les mêmes difficultés que la mise en place de votre usine à gaz mais le résultat sera bien plus fiable (et plus écolo, les ours polaires vous en remercieront).

          Ici, vous vous confrontez à un problème assez complexe qu'est l'utilisation d'API C depuis le C++.

          Beaucoup se contentes de faire du C avec ces API, et c'est le cas des exemples dans la documentation M$ : MSDN.

          Vous devriez déjà maitriser ces API avec du C avant de faire des acrobaties depuis du C++.

          Rendez votre code lisible sans valeurs magiques à la noix, je vous ai déjà indiqué qu'il fallait utiliser les constantes "VK_" :

          https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes

          Il vous manque clairement des bases si vous ne vous rendez pas encore compte que votre discours entre INT et HEX n'a aucun sens.

          HEX est un mode d'affichage/représentation des données plus compact que le binaire, mais tout ce qui est dans un ordinateur numérique est en binaire.

          INT, c'est juste, en fin de compte, un nombre de bits à une adresse mémoire particulière. Ce nombre de bits n'est même pas défini une fois pour toutes car il est fonction de paramètres de compilation.

          >Alors il faut que je crée une classe

          Attention, on définit des classes et on crée des instances d'objet (ou des objets, c'est pareil en C++).

          >que je crée un objet avec mes valeurs dedans et que j'envoie cette objet en paramètre

          C'est une manière de faire, mais le multi-thread n'est pas la solution à votre problème.

          Si le but est d'espionner le clavier et la souris, les hooks sont fait pour cela.

          Vous ne nous présentez pas la problématique initiale mais les problèmes que vous avez à implémenter la solution que vous avez choisie.

          La solution classique de génération "macro" n'a pas besoin d'un attirail aussi complexe, c'est quoi votre problème initial ?

          Pourquoi émuler des touches plutôt que de faire directement les actions qu'elles sont censées déclencher ???

          >comment faire pour que ces fonctions s’exécutent constamment ?

          Le problème n'est pas là, c'est comment arrêter proprement ces threads avant que le système ne coupe le processus et donc pouvant endommager des données, dans les fichiers, dans les mémoires partagées avec d'autres programmes, des données en cours d'envoi vers le réseau, etc...

          >Le sleep je l'ai mis pour ne pas surcharger le processeur

          Vous en faites pas pour le CPU, l'OS et l'anti-virus vous dégageront avant le moindre danger. C'est juste un truc pour compenser un peu la totale inadaptation de votre "solution".

          >et le processus d'arrêt c'est la fermeture de mon appli non ?

          Il se passe quoi quand votre processus est bloqué sur l'envoi d'un message "SentUp" et que le thread principal redonne la main à l'OS ??? (ça chie des bulles)

          >si vous avez une idée moins CACA je suis preneur !

          Si le but est d'espionner le clavier/souris : les hooks.

          Sinon, soyez plus clair sur la finalité de votre programme.

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            7 septembre 2018 à 12:42:30

            Et bien encore un grand MERCI pour votre aide. C'est vraiment super de votre port d'avoir "perdu" un peu de votre temps pour moi ! Pas mal d'infos là dedans, c'est super intéressant. Merci pour la forme :)

            > Vous ne nous présentez pas la problématique initiale mais les problèmes que vous avez à implémenter la solution que vous avez choisie.

            Comme vous voulez connaitre la problématique initiale en détail : mon programme sert à faire des macros. En gros, dans un jeu, j'ai les 4 touches pour me déplacer puis des touches pour me pencher d'un coté ou d'un autre... En plus des touches pour sprinter, sauter, recharger etc... Ça fait beaucoup de touches et en terme de maniabilité du personnage, c'est pas top à mon gout. J'aimerais qu'en fait quand je me déplace sur la gauche mon personnage se pencher à gauche automatiquement, et pareil quand je me déplace sur la droite qu'il se penche à droite, comme ça je crée seulement une touche (macro) à actionner quand je ne VEUX PAS qu'il se penche et comme c'est situation est plutôt rare, c'est beaucoup plus cohérent et moins contraignant comme façon de jouer. Il faut savoir que la touche pour se pencher (d'un coté) doit être maintenue. Du coup, si j'appuie sur Q(gauche), A(penche gauche) doit être maintenue tout le temps, même si je relâche Q(gauche). Mais je j'appuie sur D(droite), A(penche gauche) doit être relâché si elle était pressée et E(penche droite) doit être à son tour maintenue.

            En plus de ça, dans le jeu, il y a la visée à la hanche (pas précise) et la prise de visée (visée précise). A chaque fois que je fais une action (recharger, courir, sauter etc...) après l'action, le jeu me remet en visée à la hanche. Sauf que moi ça ne me sert à rien cette "visée à la hanche", je veux être toujours en "prise de visée" alors j'aimerais qu'à chaque fois que j'effectue une de ces actions en pressant une touche, je laisse un certain temps passer (le temps correspondant au déroulement de l'action) et qu'automatiquement je repasse en "prise de visée". Enfin, chacun des personnages jouables ayant des temps de rechargement différents il faut que mon temps d'attente s'adapte à eux.

            J'ai déjà crée tout ça avec autohotkey, (un éditeur de script basé sur une sorte de basic) plusieurs scripts qui communiquent entre eux et avec un jolie GUI qui me permet de changer la valeur des variables (comme des touches ou des temps de "sleep") et tout ahahah. Mais j'ai envie d'apprendre le C++ et la POO alors j'essaye petit à petit de "transcrire" mon programme en C++. L'autre langage étant plus "haut level", en quelques lignes de codes, tu fais pour faire une macro sur une touche, si tu veux en faire un objet réutilisable selon la touche c'est facile aussi. En C++, le langage étant plus bas, je dois "tout faire à la main"... C'est fastidieux mais intéressant car là où tout était "automatisé" avant, je vois chacune des étapes.

            > Faites de la dichotomie de problème, et partez de codes simples et déjà opérationnels.

            C'est bien le problème : j'ai cherché des codes de macros en C++ tout simple sur Google j'ai rien trouvé. Le seul truc que j'ai trouvé c'est en découpant les étapes : c'est du "GetAsyncKeyState" pour écouter et du "SendInput" pour envoyer.

            > Vous devriez déjà maitriser ces API avec du C avant de faire des acrobaties depuis du C++.

            Je débute déjà avec du C++, j'ai pas envie de m'arrêter là alors que je commence seulement à comprendre légèrement la POO et de réapprendre un langage en C tout de suite. Même si j'ai conscience qu'il me serait bénéfique (et logique) de procéder ainsi pour CE projet. Mais je vais déjà tacher de vraiment comprendre le C++ avant d'attaquer un autre langage, pas envie de me "perdre" dans tous ces langages et me démotiver. Je trouverai bien sur le net des façons d'utiliser ces API via le c++. Mais j'ai pris note de la difficulté d'utiliser des API, pour mon niveau, j'ai pris en compte votre mise en garde et j'essayerais de faire sans, quand je le peux.

            > Rendez votre code lisible sans valeurs magiques à la noix, je vous ai déjà indiqué qu'il fallait utiliser les constantes "VK_"

            Et ça n'est pas tombé dans l'oreille d'un sourd, croyez le, tout ce que vous me dites je l'analyse et cherche à le comprendre avec mon niveau. Le prisme de la noobitude peut parfois déformer les informations ! Je ne comprends pas votre requête puisque c'est ce que j'ai l'impression de faire, donc effectivement je ne dois pas avoir compris un truc...

            Je vous (ré)explique, plus clairement, ce que JE PENSE avoir fait, et vous me dites ce que j'ai mal interprété : J'ai également trouvé mes valeur de Virtual Key que je vous ai fourni dans mon code initiale sur microsoft.com. Seulement vous remarquerez que sur les touches dont j'ai besoin (le Q et le A) les valeurs VK sont de l'hex 0x51 et 0x41. Moi, j'ai essayé d'utiliser celles-ci pour dialoguer avec l'API.  Par exemple le VK de la touche a, c'est 0x41, j'ai essayé de lui filer en string en pensant que l'API (qui a un fonctionnement particulier) s'en moquerait : pour lui que j'écrive 0x41 directement dans le code ou que je lui donne le nom d'une variable qui a 0x41 comme valeur, il prendrait cette formule et la mettrait en INT dans son langage. Bon, en fait il faisait quand même attention a mon type de variable (string). Alors il veut du int ? Je vais lui donner du type int, mais comme je ne peux pas afficher (représenter) une valeur en base 16 dans mes variables int, je donne cette valeur en décimal (81) mais j'aurai surement pu le donner en binaire(1010001). Je me suis dit la valeur est la même et c'est du INT, mais dans le fonctionnement de l'API (qui est un langage méconnu) peut être veut'il qu'il soit représenté en hexadécimal comme sur le schéma. Bon, en fait, du moment qu'il a le bon nombre, apparemment il s'en fout du mode de représentation. Ok, suis-je a coté de la plaque ou ? J'ai juste été bête et discipliné, si c'est bon. J'ai vu (ou cru comprendre) que certain code ou fonction en C++ n'aime pas que l'on lui fournisse du décimal alors qu'il s'attend à du hexadécimal (il ne sait pas faire la conversion). Je me suis dit que l'API je vais lui fournir le chiffre qu'elle attend dans le mode de représentation qu'elle attend...

            Bref, vous allez encore me prendre pour un con, mais je ne savais pas que la dénomination VK_A ou VK_Q existe pour l'API... Je me suis qu'il avait crée des dénominations "VK_" pour les touches spéciales et que pour les touches de lettres c'était seulement du 0xXX. Pourquoi ? Sur le site de microsoft c'est pas écrit VK_A pour la touche A. Bête et discipliné, moi je ne spécule pas, on me fournit des infos je ne fais qu'avec ces infos, pas envie de m'attirer des problèmes, je fais avec les outils que l'on me donne !

            Alors j'ai un problème avec " je vous ai déjà indiqué qu'il fallait utiliser les constantes "VK_""

            Si vous parlez des valeurs binaires, je pensais l'avoir fait. Si vous me parlez des dénominations : VK_A et VK_Q, vous allez me tuer mais moi je ne sais pas stocker des lettres dans du INT. Car ça n'a pas de sens de stocker des lettres dans une variable d'un type qui ne traite que des chiffres. Et je ne peux pas stocker les dénominations littérales dans du string et le filer à l'API pour qu'elle deal avec... Elle ne veut que du INT (un chiffre quoi). Ou alors je convertis mon VK_A en binaire (puisqu'au final les lettres ne sont que des chiffres : des 1 et 0, comme le binaire ou le hex) mais bon ça me fait une étape supplémentaire pour... rien. Alors désolé mais faut m'expliquer plus en détail ce que vous attendez de moi, je n'y comprends rien. :s

            > Je pense que le "hooking" des évènements claviers et souris serait bien plus propre.

            Super info ! Quand j'ai fait mes recherches je n'ai pas entendu parlé de hooking ! Je vais m'empresser d'étudier la chose. Bon, ça reste du Win32 et vous me faites peur avec ça ahahah Je vais essayé de trouvé des codes fonctionnels et tout fait pour éviter les conneries. En plus je pensais qu'en fermant le thread principal, si je codais un truc, je pourrais dire au thread secondaire de tout interrompre, d'effacer de désalloué la mémoire et de se fermer aussi. Mais ça j'en étais pas encore là.

            > Il vous manque clairement des bases si vous ne vous rendez pas encore compte que votre discours entre INT et HEX n'a aucun sens.

            Suivit de vos explication sur HEX et INT. J'ai l'impression de le savoir déjà. Soit j'ai vraiment rien compris aux bases et j'arrive même pas à m'en rendre compte à cause de ma vision erronée, soit je m'étais mal exprimé et je n'ai pas su vous faire comprendre au passage que je comprenais que les types INT / string / bool / etc... tous ne stockent que du 1/0 mais quand on les appellent (ces données) elles ont des représentations différentes selon ce que l'on veut en faire de ces infos.

            > Attention, on définit des classes et on crée des instances d'objet (ou des objets, c'est pareil en C++).

            Oui, je pense avoir saisit et c'est très intéressant pour moi de bosser là dessus en tant que débutant. Et ici, c'était un moyen de m'entrainer à le faire. C'est un peu le but de mon programme pour moi : définir des fonctions, des classes, structurer tout ça dans plusieurs fichier de façon logique, créer des instances objets via ces classes aussi, puis appeler le tout depuis le main en les faisant interagir entre elles, après plus tard je me pencherais sur un GUI et aussi le changement de comportement de mon programme via ses fenêtres (et donc les variables ou attributs). Je devrais me heurter à pas mal de problèmes mais ça me fera progresser de les résoudre.

            > Le problème n'est pas là, c'est comment arrêter proprement ces threads avant que le système ne coupe le processus et donc pouvant endommager des données, dans les fichiers, dans les mémoires partagées avec d'autres programmes, des données en cours d'envoi vers le réseau, etc...

            Je ne m'étais pas encore penché sur la fermeture de tous les threads. J'essayais déjà qu'ils fassent quelque chose. Par contre effectivement va falloir que, lorsque je me pencherai sur cette étape, je fasse ça bien. C'est dangereux".

            > Vous en faites pas pour le CPU, l'OS et l'anti-virus vous dégageront avant le moindre danger. C'est juste un truc pour compenser un peu la totale inadaptation de votre "solution".

            C'est intéressant aussi là ! Pourtant sur visual studio, on peut voir la consommation du processus, et avec un sleep ça l'atténuait beaucoup et lorsque je ne le mettais pas l'AV et l'OS ne faisait rien. Oui, c'est surement du bricolage, mais le seul outil que je connais pour l'instant. Avec du hooking je n'aurais peut être plus à faire de boucle "caca" et à mettre du "sleep" pour compenser ce "caca" effectivement.

            > Il se passe quoi quand votre processus est bloqué sur l'envoi d'un message "SentUp" et que le thread principal redonne la main à l'OS ??? (ça chie des bulles)

            Je pensais, qu'en closant le thread principal, j'aurai coder une instruction à effectuer avant qu'il se coupe où il ordonnerait aux threads secondaires d’arrêter ce qu'il font, de redonner la mémoire puis de se couper.

            Encore merci pour votre aide bacelar ! :) Grace à vos infos je progresse ! Je vais me documenter sur le hooking !

            • Partager sur Facebook
            • Partager sur Twitter
              10 septembre 2018 à 15:13:15

              Je commence à comprendre pourquoi vous n'avez pas assez bien assimilé les bases.

              Vous avez une expérience avec un outil de scripting et vous n'avez pas été très attentifs sur les aspects typages statiques des variables.

              Sauf erreur de la part "autohotkey" est un projet OpenSource C++, il serait donc plus pertinent de voir son code source (une roue qui a déjà roulée) que d’essayer de faire une roue carrée avec vos minces connaissance. Si vous n'arrivez pas à comprendre son code source, c'est encore plus compliquer de partir de zéro que de comprendre un code source, donc ...

              Ce que vous tentez de réaliser n'est clairement pas à la portée d'un débutant, même très très doué.

              Je vous conseille donc très chaudement de changer de projet pour l'apprentissage du C++.

              >c'est du "GetAsyncKeyState" pour écouter et du "SendInput" pour envoyer.

              C'est pas du C++, c'est du C.

              Généralement, cela fonctionne assez mal pour les jeux et je vous laisse regarder le code source de "autohotkey" pour remarquer que ce n'est pas si simple.

              >Je débute déjà avec du C++

              Changez de projet, c'est beaucoup trop complexe pour un débutant.

              > et de réapprendre un langage en C tout de suite.

              Vous connaissiez le C et vous ne faites pas la distinction entre le type statique d'une variable et le mode de représentation des valeurs ??? o_O

              >Même si j'ai conscience qu'il me serait bénéfique (et logique) de procéder ainsi pour CE projet.

              Pas du tout si vous utilisez une API C.

              Mais comme votre projet, c'est plus de la bidouille de programmation système, c'est pas gagné qu'il y ait une encapsulation C++ de cette API. C'est aussi pour cela que je vous enjoint de changer de projet.

              >c'est ce que j'ai l'impression de faire

              Ce que vous prenez en référence ne semble pas avoir une liste exhaustive des VK_:

              http://winapi.freetechsecrets.com/win32/WIN32VirtualKey_Codes.htm

              La liste des VK_ déjà disponibles est fonction des options de compilation, et ajouter un "#define VK_xxx... ; x=VK_xxx;" à la place de ces horribles "... = 0x51;" et autre "... = 041;", c'est quand même bien plus lisible.

              >j'ai essayé de lui filer en string en pensant que l'API

              L'API est une API C, "string", c'est une classe C++, donc incompréhensible par une API C. Une API C comprend du "char*" à la rigueur, mais si vous lisez la documentation de l'API, ici, c'est des INT qu'il attend, des codes VK_, pas des lettres.

              >lui donne le nom d'une variable qui a 0x41 comme valeur

              Utilisez directement les constantes "VK_xxx", pas besoin ni de variables, ni de valeur en dure dans le code.

              >Alors il veut du int ?

              Oui, comme indiqué explicitement dans la documentation.

              >je ne peux pas afficher (représenter) une valeur en base 16 dans mes variables int

              Bin si.

              int toto = 0x41;
              //mais avec des constantes, c'est mieux
              int titi = VK_A;

              >qu'il soit représenté en hexadécimal comme sur le schéma

              On s'en fout de la représentation, seul le type statique compte.

              >VK_A et VK_Q, vous allez me tuer mais moi je ne sais pas stocker des lettres dans du INT

              C'est déjà des int, ne les définissez pas, les "#define ..." qui les définissent, dans les oncludes système, ont déjà une formulation de déclaration "int compatible".

              >Car ça n'a pas de sens de stocker des lettres dans une variable d'un type qui ne traite que des chiffres.

              Ce n'est pas des lettres, c'est des codes de touche qui ne sont pas des lettres mais des nombres. Que les nombres des touches virtuelles pour les lettres correspondent au code ASCII US des lettres est "un heureux hasard".

              >je pourrais dire au thread secondaire de tout interrompre

              Et vous comptez le lui dire comment ? :-°

              >Mais ça j'en étais pas encore là.

              Quand on décolle avec un avion, on prévoit avant un moyen d’atterrir, dans le développement, c'est pareil.

              >je comprenais que les types INT / string / bool / etc...

              Le C++ est un langage à typage statique fort, une variable a un type défini du début à la fin du programme. La manière dont sont stockées les informations est fonction du type de la variable, mais que vous initialisez une variable à partir d'une constante exprimée en hexadécimale ou en décimale ou en octal etc... ne change en rien comment cette information est stockée (c'est toujours en binaire).

              >Et ici, c'était un moyen de m'entrainer à le faire.

              L'utilisation d'une API C force à utiliser assez salement le C++, c'est donc un très mauvais exercice.

              > J'essayais déjà qu'ils fassent quelque chose.

              Cf. les navions qui décollent.

              > je ne le mettais pas l'AV et l'OS ne faisait rien

              Parce que votre machine n'a pas été mise en coupe réglé par un administrateur compétent. Votre machine n'est cas particulier, elle ne prouve rien.

              > il ordonnerait aux threads secondaires d’arrêter ce qu'il font

              Il est balèze, mais non, s'il attend une réponse des threads et qu'ils ne répondent pas, c'est la merde.

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

              Utiliser variable pour VirtualKey dans API

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown