Piloter une autre application

Messages postés
67
Date d'inscription
dimanche 16 octobre 2005
Statut
Membre
Dernière intervention
13 novembre 2009
- - Dernière réponse : jnmchl
Messages postés
67
Date d'inscription
dimanche 16 octobre 2005
Statut
Membre
Dernière intervention
13 novembre 2009
- 29 mars 2008 à 13:39
Bonjour,


Je cherche à faire une application qui sert d'interface entre une application personnelle et une application professionelle : j'explique l'historique et le boulot :
Je dois traiter des données que j'exploite selon ma stratégie et que je devais jusque là rendre à ma direction sous forme de fichier XLS selon un canevas fourni. Pour gagner du temps, je me suis fais une application sous Delphi pour m'aider dans le traitement de ces données et qui inclue également des fonctions propres à ma stratégie, cette appli générait directement le fichier XLS demandé par ma direction. J'ai ainsi toujours obtenu de bons résultats fiables et rapides.
Aujourd'hui, la direction a changé son logiciel : mon boulot reste le même sauf que la direction ne veut plus de fichiers XLS mais les données doivent être saisies par moi dans une interface reliée au système. J'ai râlé mais ma direction ne veut rien entendre : pour eux ils me demandent le même boulot mais au lieu de saisir sous XLS je dois saisir dans leur interface (au demeurant pas très ergonomique). Sauf que moi, je perds un temps précieux à ressaisir tout ce que me crache mon application et qui se fait au détriment de la quantité et qualité de mon travail.
En fait, je me suis renseigné et j'ai un peu exploré le système : leur interface est juste un masque de saisie et quelques contrôles de cohérence écrit en Visual Basic connecté à une base ORACLE avec Tuxedo. Je m'interdis d'entrer directement dans la base : c'est trop risqué. Mon idée est donc de faire une appli d'interface pour saisir à ma place et transférer mes données dans leur interface VB.


En utilisant GetWindows, GetNextWindows et SendMessage, j'arrive à lire et écrire dans les contrôles via leur handle. Un essai manuel et partiel fonctionne. Reste maintenant à être séquentiel et tout mettre dans le bon ordre, mais là j'ai un problème qui fait l'objet de ma question :


Les handles changent à chaque fois que l'appli est relancée : je ne peux donc pas les mémoriser, et d'essayer d'identifier quel handle correspond tel ou tel autre contrôle à chaque fois est long et fastidieux.
Donc, comment reconnaitre à coup sûr qu'un numéro de handle correspond bel et bien à un contrôle donné ?
Avec GetWindowText je récupère bien le texte pour les boutons, mais sur des onglets différents : il y a des boutons différents qui portent le même caption (Valider, Annuler ...), et en plus il y a beaucoup de TextBox (ThunderRT6TextBox) ... qui eux n'ont pas de texte ?  
Comme je ne suis pas l'auteur de l'interface en VB je ne connais pas la structure de la form, je me demande s'il est possible de récupérer le nom (la propriété Name) que l'auteur à donné à chaque composant pour m'adresser à son handle de manière sûre ? un "GetComponentName" ?
Ou existe-t-il un autre moyen ? les retrouver par leurs coordonnées top, left : avec les onglets ce n'est pas fiable et je ne sais pas comment faire ? ou l'ordre chronologique de création ?   


De plus, j'ai une autre question comment remplir avec SendMessage les cellules d'un tableau MSFlexGridWndClass ?


J'espère avoir été assez clair dans ma requête, bien sûr je n'attends pas forcément la solution entière mais si ceux d'entre vous qui connaissent un peu le sujet peuvent apporter une brique à l'édifice, ou émettre une idée ... merci d'avance. Même si je programme surtout en Delphi des explications sous VB ou C++ sont les bienvenues.

Jean-Michel
Afficher la suite 

4 réponses

Messages postés
968
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
0
Merci
Un moyen peut-être efficace serait, si ta fenêtre a toujours la même configuration, de simuler des clicks de souris sur les différents TextBox, et l'envoi de codes touches claviers associés...cela te permettrait de remplir tes champs de manière automatisée.
Apis utiles pour cela : SendInput(), FindWindow(), GetWindowRect()...
Commenter la réponse de cs_juju12
Messages postés
67
Date d'inscription
dimanche 16 octobre 2005
Statut
Membre
Dernière intervention
13 novembre 2009
1
0
Merci
Merci Juju.
Oui, j'avais pensé à une espèce d'automate : càd qu'en connaissant les emplacements des différents contrôles simuler la position de la souris, les clics doubles clics et  le clavier ... mais : 
1) ça me paraissait pas très pro et puis faut s'assurer que la fenêtre soit toujours au même endroit
2) mais ça ne permet une saisie semi automatique car il y a aussi un ListBox (non modifiable) cette liste est renseignée en fonction de plusieurs critères (que je ne maîtrise pas) donc l'idéal est de lire le contenu pour faire le bon choix (avec le handle et sendmessage : je sais faire).
3) Avant de faire une validation finale j'aurais voulu vérifié que chaque champ est bien renseigné car j'avais détecté quelques moments où l'interface ne donne pas la main à l'utilisateur.

Jean-Michel
Commenter la réponse de jnmchl
Messages postés
968
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
0
Merci
1) peu importe que ça fasse pro ou pas si ça t'aides dans ton boulot je suppose
quant à la position de la fenêtre c'est pas obligé, suffit de récupérer sa position par GetWindowRect() et de travailler avec des coordonnées relatives au coin supérieur gauche
2)  ah OK dans ce cas...
Faut en revenir à ta méthode de communication avec les contrôles. Tu peux énumérer toutes les fenêtres filles (FindWindowEx) et vérifier à chaque fois leur position (GetWindowRect); comme ça tu pourrais recréer une liste de hwnd sur tes différents contrôles. Cependant, si t'as plusieurs onglets...tu peux essayer de récupérer le hwnd de l'onglet affiché et le spécifier comme parent à FindWindowEx, comme ça peut-être que t'auras que les contrôles qui sont dessus...tu pourrais aussi utiliser GetWindowFromPoint(Ex) avec ce hwnd, pour éviter d'énumérer tous les contrôles...ou mieux peut-être appeler GetNextWindow () jusqu'à la dernière fenêtre possible, tu seras sûr d'avoir le contrôle en question.
Commenter la réponse de cs_juju12
Messages postés
67
Date d'inscription
dimanche 16 octobre 2005
Statut
Membre
Dernière intervention
13 novembre 2009
1
0
Merci
Oui, il y a sans doute possibilité d'utiliser plusieurs méthodes, ce que j'essaie de savoir c'est quand j'énumère tous les contrôles (qu'il soient cachés ou non par un onglet) j'obtiens :
 - leur handle
 - le nom de classe
 - le texte de fenêtre (quand il existe)
 - avec GetWindowsRect j'ai même les coordonnées
pourtant je peux avoir un TextBox avec les mêmes coordonnées, le même nom de classe et pas de texte de fenêtre ... y'en a un c'est pour le nom du client, l'autre pour un index de produit ... 
Effectivement si je regarde quel onglet est ouvert et quels sont les coordonnées du contrôle je peux m'en tirer ... 
Je vais aussi vérifier si l'ordre d'énumération avec GetNextWindow est aussi toujours le même ... ce qui constituerait de bonnes pistes.
Mais là je pensais qu'il existe un "GetWndComponentCreateName" ou un truc du genre. Sur un autre forum, j'ai lu qu'un auteur identifiait ses contrôles par un tag ... sauf que moi je ne suis pas l'auteur de l'appli que je cherche à piloter.
Merci pour cette piste, quoiqu'il en soit, je posterai ma réponse dès que j'aurai un truc qui fonctionne.   

Jean-Michel
Commenter la réponse de jnmchl