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 :

Message vers une fenêtre qui n'est pas au premier plan


Sujet :

C++

  1. #1
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut Message vers une fenêtre qui n'est pas au premier plan
    Bonsoir à tous,
    j'ai cherché longuement sur la manière d'envoyer des messages à une fenêtre qui n'est pas au premier plan, et j'ai beaucoup de mal à comprendre pourquoi certains codes marchent et d'autres non:
    Ce code censé simuler l'appui de la combinaison ctrl+P sur une fenêtre dont on a au préalable récupéré le handle, ne fonctionne pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
         PostMessage(fenetre,WM_KEYDOWN,VK_CONTROL,0);
         PostMessage(fenetre,WM_KEYDOWN,'P',0);
         PostMessage(fenetre,WM_KEYUP,'P',0);
         PostMessage(fenetre,WM_KEYUP,VK_CONTROL,0);
    Pourtant ce code fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
         PostMessage(fenetre,WM_KEYDOWN,VK_SPACE,0);
         PostMessage(fenetre,WM_KEYUP,VK_SPACE,0);
    (ce dernier fonctionne sur certains programme, mais pas sur le bloc notes, ce qui est encore plus bizarre...)
    Donc si quelqu'un peut m'éclairer (surtout sur la simulation de combinaison de touches sur une fenêtre qui n'est pas au premier plan),
    je le remercie d'avance.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Ce que vous tentez de faire avec ces appels, c'est de "truander" le programme cible.
    Le programme cible n'est pas obligé de se faire "avoir" par votre "astuce".

    Des programmes utilisant des API comme DirectInput ou autre n'utilisent pas du tout les messages "WM_KEYUP/WM_KEYDOWN", etc...

    C'est quoi votre "vrai" besoin, à part "truander" ces pauvres programmes.

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Ce que je soupçonne c'est que les touches ne sont pas combinées (<- *)

    Parce que le comportement de Windows est

    1) je reçois la touche CTRL (message WM_KEYDOWN) -> j'attends
    2) je reçois la touche P (message WM_KEYDOWN) -> je combine les touches, j'envoie le message CTRL+P (message WM_CHAR)
    3) la fenêtre reçoit le message CTRL+P

    .... et ainsi de suite jusqu'aux messages WM_KEYUP

    Mais en lisant stackoverflow , les messages CTRL+P ne contiennent pas forcément un code CTRL et un code P (<- Windows style)

    Handling keyboard input in win32, WM_CHAR or WM_KEYDOWN/WM_KEYUP? (<- lien stackoverflow en anglais)

    Apparently, windows works in really strange ways. [...] It seems that when you press [shift]+9, windows sends a VK_LEFT in the wParam of message WM_CHAR

    * Édit : parce que la touche espace fonctionne pour un logiciel mais pas CTRL+P qui est la combinaison de 2 touches en 1 message

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Le "CTRL+P" n'est pas généré par Windows directement. C'est le "TranslateMessage" de votre application qui convertie les WM_KEYDOWN en WM_SYSKEYDOWN/WM_SYSCOMMAND.
    Si votre application n'utilise pas de "TranslateMessage" pas de raccourci, pas de Print.

  5. #5
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Bonsoir et merci pour ces réponses,
    y a-t-il alors un moyen de simuler l'appui de touches sur une fênetre qui n'a pas le focus (équivalent de la fonction keybd_event pour une fenêtre visée en particulier, sans devoir la mettre au premier plan).
    Sinon Bacelar, je n'ai pas trop compris ta dernière réponse; il faut convertir les WM_KEYDOWN en WM_SYSKEYDOWN/WM_SYSCOMMAND avec la fonction TranslateMessage? Mais comment ? il faudrait créer un objet de type MSG, exécuter la fonction translate dessus? mais comment faire si c'est bien cela qu'il faut faire?

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    "keybd_event", c'est aussi une astuce.
    Elle est plus bas niveau, donc plus de programme se font avoir.

    il faut convertir les WM_KEYDOWN en WM_SYSKEYDOWN/WM_SYSCOMMAND avec la fonction TranslateMessage?
    Non, c'est l'application que t'essaye de blouser qui fait son traitement pépère, généralement, en appelant la fonction "TranslateMessage" de Win32 pour convertir les WM_KEYDOWN en WM_CHAR.
    Il suffit que l'application que t'essaye de blouser utilise une méthode de traitement qui ne fonctionne pas avec ton arnaque (comme GetAsyncKeyState https://docs.microsoft.com/en-us/win...tasynckeystate) pour que ta combine ne fonctionne pas.

    C'est quoi votre "vrai" besoin, à part "truander" ces pauvres programmes.
    (BIS)

  7. #7
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Bonsoir,
    Mon but est de comprendre mieux comment marchent les messages, et mon application pratique était de pouvoir mettre en pause le windows media player, mais je viens de trouver une solution plus efficace à cette application pratique en observant les messages de la fenêtre du lecteur dans spy++:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //UTILISER:
    PostMessage(FindWindow("WMPlayerApp",0),WM_COMMAND,0x14978,0);
    //AU LIEU DE:
    PostMessage(FindWindow("WMPlayerApp",0),WM_KEYDOWN,VK_SPACE,0);
    PostMessage(FindWindow("WMPlayerApp",0),WM_KEYUP,VK_SPACE,0);
    (remarque: les codes 0x14978 et 0 pourraient peut-être être différent pour une autre version du lecteur de musique)
    Mais ça n'empêche pas que si je peux trouver des informations plus précises sur les messages ça m'intéresse.

    * Édit : parce que la touche espace fonctionne pour un logiciel mais pas CTRL+P qui est la combinaison de 2 touches en 1 message
    Effectivement, ce doit être le problème.
    Merci des réponses.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par racine carrée Voir le message
    Mais ça n'empêche pas que si je peux trouver des informations plus précises sur les messages ça m'intéresse.
    La référence c'est cette page A Key’s Odyssey ... par contre c'est long, tortueux (prévoir de l'aspirine ) et peut être daté/ obsolète


    Édit: c'est spécifique à la bibliothèque VCL (Delphi/ C++), surcouche de la Win32, donc peut être HS.

  9. #9
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Merci beaucoup,
    je lirai ça quand j'en aurai le temps.
    c'est long, tortueux (prévoir de l'aspirine )
    ... et surtout c'est de l'anglais !

  10. #10
    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 519
    Points
    41 519
    Par défaut
    La raison principale pour laquelle la méthode PostMessage() pour les touches ne marche pas, c'est que la gestion du Keyboard State en est indépendante.

    keybd_event() et SendInput() génèrent des "vrais" appuis de touches, mais ne permettent pas de cibler une fenêtre: Tout part vers ce qui a le focus.

    À ma connaissance, il n'existe pas de fonction cumulant les avantages des deux, et Microsoft ne semble pas avoir d'intention d'en ajouter une, vu que ce n'est pas comme ça qu'un programme est supposé être "automatisé" (supporter OLE Automation ou Active Accessibility, c'est ce qui est recommandé à la place).

    Pour tout ce qui utilise directement l'API Win32 ou tout ce qui en est "assez" proche, un bon WM_COMMAND doit suffire pour la plupart des fonctionnalités. Mais on ne peut en dire autant de Windows Forms (qui ne semble pas permettre de spécifier un Control ID) ou d'un framework dit "windowless"...
    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.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 071
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 071
    Points : 12 116
    Points
    12 116
    Par défaut
    Pour le pilotage du Windows Media Player, il y a beaucoup beaucoup plus simple :
    https://www.howtogeek.com/howto/1935...-media-player/
    (Usage des "global hotkeys")

    J'ai l'impression que vous subissez le syndrome du marteau de Maslow (quand on ne connait que le marteau, tous les problèmes ressemblent à des clous).

    Comme l'indique @Médinoc, le hacking des touches claviers, et des messages Windows pour autre chose que leur fonction première (cf. WM_COPY et consort), c'est clairement de la bidouille que M$ n'encourage pas.
    C'est déjà bien assez l'enfer pour la rétrocompatibilité avec les fonctionnalités qu'ils ont documentées, alors s'ils font l'erreur de simplifier ces immondes bidouilles, c'est la fin des haricots.

    La référence de @foetus, c'est ce qui se passe DANS l'application, et chaque framework, VCL, MFC, .NET gère les messages de la file de message d'un thread graphique selon SA tambouille.

    Résultat, des bidouilles qui fonctionnent avec des applications faites avec un framework ne fonctionneront pas forcement avec un programme écrit avec un autre framework. Et comme c'est une partie "user" du programme, les développeurs des applications sont tout à fait à même de changer le comportement du framework pour leurs besoins et donc une bidouille qui fonctionne avec un programme qui utilise un framework peut ne pas fonctionner sur un autre programme qui utilise le même framework.

    En résumé, comme l'indique @Médinoc, utilisez les API de pilotage du programme que fournit le programme et arrêtez de tenter de le blouser.

    L'usage du PostMessage avec un WM_COMMAND DOCUMENTE peut très bien servir d'API officiel, mais il faut que cela soit documenté. Sinon, à la prochaine version, voir à la prochaine mise à jour ou installation de plug-ins, vous l'aurez dans le baba.

    Mais ça n'empêche pas que si je peux trouver des informations plus précises sur les messages ça m'intéresse.
    Ce traitement des messages est en zone "user", chaque programmeur est libre dans faire ce qu'il veut.
    Il peut utiliser des routines pré-construite par l'OS, comme DefWindowProc (https://docs.microsoft.com/en-us/win...defwindowproca), ou, plus couramment par une framework graphique (qui peut utiliser les routines de l'OS mais pas forcement, cf. les framework JAVA), MAIS le développeur est totalement libre de tout changer (ce que font bon nombre de "gros" programmes, comme Photoshop, etc...).

    Ce qui est "constant" c'est ce qui se passe avant qu'un message provenant du système se retrouve dans la file de message d'un thread graphique.
    - interruption matériel du périphérique ou du bus
    - prise en charge par le driver matériel des informations à collecter sur le périphérique
    - remonter dans la pile des drivers des informations avec transformation si nécessaire
    - prise en charge d'évènements "Kernel" comme le Ctrl-Alt-Sup ou le "Alt-Tab" ou encore les "global hotkeys"
    - passage de l'évènement à toutes les routines de "hooking système" enregistrées sur ce type d'évènement (si les routines de hooking sont bien programmées et foutent pas la grouille).
    - dépôt dans la file de message d'un thread cible de l'évènement.
    - passage de l'évènement à toutes les routines de "hooking utilisateur" enregistrées sur ce type d'évènement.

  12. #12
    Membre habitué Avatar de racine carrée
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2018
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2018
    Messages : 156
    Points : 137
    Points
    137
    Par défaut
    Merci beaucoup de ces réponses.
    Ceci m'a bien éclairé sur la notion de messages dans Windows (même s'il me reste encore beaucoup de travail de compréhension et d'application à faire).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 03/06/2017, 21h40
  2. Tracé d'une ellipse qui n'est pas dans le plan
    Par Petit Taupin dans le forum Mathématiques
    Réponses: 2
    Dernier message: 13/06/2016, 10h45
  3. Impression vers une imrimante qui n'est pas par défaut
    Par abdelghani_k dans le forum Delphi
    Réponses: 5
    Dernier message: 22/05/2007, 12h07
  4. Trouver une valeur qui n'est pas dans un champ
    Par eric41 dans le forum Requêtes
    Réponses: 6
    Dernier message: 16/05/2006, 16h48
  5. lien dessus une images qui n'est pas en background
    Par tiyolx dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 04/03/2006, 18h40

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