Utilisation de DoEvents pour reprendre la main sur une appli VB
rol64
Messages postés33Date d'inscriptionlundi 21 janvier 2008StatutMembreDernière intervention28 novembre 2011
-
27 févr. 2009 à 12:05
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 2021
-
4 mars 2009 à 09:55
Salut tout le monde!!
J'ai un petit souci avec une application VB que je suis en train de développer, dont le but est de répéter une séquence de raccourci clavier à une fenêtre précise sous windows. Mon pbm principal est que je perds la main sur mon application VB dès lors qu'une procédure est en cours.....
Le code source de ma procédure associée à un button_click:<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>
La fonction de cette procédure est d'envoyer en boucle l'évènement clavier F2 à la fenêtre d'une application différente (application sous SAP), que j'active en début de procédure avec l'API 'SetForegroundWindow' afin d'automatiser une tâche extrêment simple mais à effectuée beaucoup de fois (entre 5 et 150 fois....).
Sachant qu'à partir du moment où l'appuie sur la touche F2 a été simulé, la tâche exécutée sous l'application prend un temps variable allant de 15 à 25 secondes. Ainsi, que le processus engendré par l'appuie de F2 dure 25 seconde ou moins, il y aura toujours ma temporisation de 30 secondes, ce qui implique une perte de temps....
J'ai donc une première question: existe-t-il un témoin quelque part ou une API particulière permettant de m'affranchir de ma temporisation Sleep, afin de piloter l'incrémentation de mon index i à l'intérieur de ma boucle For avec un indicateur de fin du processus associé à un précédent appuie sur F2? (J'espère que ce que je raconte est claire et compréhensible...) J'avais pensé au son wue Windows génère quand la tâche est terminée... Je me suis dis que ce son est tracée dans une varibale et que pour que ce sont soit généré à la fin de la tache il doit bien y avoir quelque part une variable indicatrice de fin de processus?!!!
Une deuxième question est liée au souhait d'ajouter un bouton pour interrompre ma boucle, j'ai lu qu'il y avait un moyen de redonner la main à Windows avec une certine fonction DoEvents, cependant je ne suis pas sur d'avoir bien compris son fonctionnement... De ce dont j'en ai compris j'ai modifié mon code de la facon suivante, en utilisant une variable booléenne associée à un évènement command2_click():
Cependant, ca ne marche pas, à partir du moment ou je lance la boucle je perds complètement la main jusqu'à la fin de la boucle. L'icône de la souris est constamment doublé du petit sablier lorsque je plcae mon curseur sur l'application "Séquence_clavier" et si je tente de cliquer sur le bouton interrompre le message "(ne répond pas)" vient s'accoler à côté de du nom de mon application dans la barre de titre.... Je suis donc obligé de terminé le processus en passant par le gestionnaire de tache CTRL+MAJ+ECHAP et de faire Applications>Fin de Tache pour sortir du programme.... Pas très classe ni très pro me direz vous...
Je voudrais joindre a feuille VB6 afin que vous puissiez faire le test vous même... Mais je ne sais pas ou est ce que l'on peut attacher un fichier sous ce forum... Pouvez vous m'aider? Après vous pourrez faire le test comme suis :Pour faire le test ave l'application calculatrice de Windows, vous devez lancer la calculatrice, récupérer le hWnd de la calculatrice à l'aide du bouton "Voir les fenêtres", renseigner le champs ID Wnd treated, donner le nombre de répétition de l'appuie de la touche F10 (ici je tavail avec F10 plutot qu'avec F2, car F2 n'a pas d'effet sous la calculatrice. En revanche F10 surligne/désurligne en bleu l'onglet "Edition" du menu de la calculatrice...). J'ai aussi modifié la durée du sleep pour accélerer la boucle et voir les effets à une échelle de temps d'attente plus acceptable dans le cadre d'une procédure de débuggage...
J'ai une certine intuition quand à l'origine du bloquage mais je n'en suis pas certain... Pour moi il ya a une histoire de changement de handle perturbé/non gérer par mon application: en effet lorsque je clique (enfin plutot lorsque que je veux cliquer sur le bouton interrompre, cela implique que le l'envoi des séquences F2 s'applique à mon application et non plus à la fenêtre que je désire... Et j'arrive donc à ma troisième question: est il possible verrouiller un handle sur une fenêtre précise afin que la séquence clavier s'applique à une fenêtre spécifique, que je clique ou non sur une autre fenêtre, et donc que je fasse passer ma fenêtre en second plan...
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202172 27 févr. 2009 à 12:18
Sleep bloque ton appli.
donc faut cliquer au bon moment, pour que ca soit pris en compte ^^
fais un plus petite pause, mémorise le résultat de l'API GetTickCount
après avoir fait ton envoi de touche
ensuite, tu boucle tans qu'un certain temps n'est pas passé (GetTickCount - nStartTime > 30 ) ...
rol64
Messages postés33Date d'inscriptionlundi 21 janvier 2008StatutMembreDernière intervention28 novembre 2011 2 mars 2009 à 11:26
SAlut,
Merci pour ta réponse Renfield! Je pense que je vais abandonner la solution sleep qui est très simpliste au début mais qui me complique pas mal la tâche... Je cherche donc une autre solution qu'une temporisationqui me fait perdre du temps car l'évènement généré par F2 dure un temps variable lors que ma temporisation est fixée sur une variable précise... Je cherche donc à trouver un moyen de remplacer le sleep par une variable témoin de la fin de l'évènement généré par le F2 précédent... Sais tu s'il existe une api permettant d'être averti lors de la fermeture d'une fenêtre? J'avais pensé au son généré par windows lorsque la tâche est terminé....
A+
aserf
Messages postés114Date d'inscriptionlundi 15 avril 2002StatutMembreDernière intervention 1 juillet 2011 2 mars 2009 à 16:57
Salut,
Est ce que tu na ps moyen de voir le handel de la fenetre ou sont nom, et de boucler sur l'ensemble des fenetre pour voir si elle existe, si elle n'es plus la ... le traitement est terminer,
a++
seb
Développement Rapide PHP / VBNET -> www.database2code.com
rol64
Messages postés33Date d'inscriptionlundi 21 janvier 2008StatutMembreDernière intervention28 novembre 2011 3 mars 2009 à 17:41
Salut Aserf,
J'ai creusé du côté de ta proposition qui est vraiment astucieuse cependant je me vois dans l'impossibilité de la mettre en oeuvre vu que la fenêtre en question ne se ferme pas à la fin de la tâche.
En revanche j'ai constaté qu'il y a un message qui apparait à la fin de la tâche en bas de la fenêtre principale de l'application, dont le contenu est différent à chaque fois (car en rapport avec l'objet traité par la tâche). Le message apparait en bas de la fenêtre, dans une zone que j'appelerai la barre de dialogue. Je voudrais savoir si il existe une quelconque API windows me permettant de récupérer ce message dans une variable, sachant que je dispose du handle de cette fenêtre??? J'avais pensé à GetWindowText mais il semble que je ne peux récupérer que "le titre d'une fenêtre, d'un contrôle ou d'une zone de saisie".
Merci pour ton aide! Je continue à creuser de mon côté...
A+
roland
C'est un tutoriel sur le subclassing (ou sous classement) pour intercepter les messages windows. Il est vraiment bien fait, en plus en VB... Donc que du bonheur.... Je pense que je suis pas loin de trouver la solution!!! Il semble que l'info de fin de tâche qui s'affiche dans la barre d'état de ma fenêtre SAP est bien récupérable!!!!
Merci encore!!!
A+