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

MFC Discussion :

Surveiller une TextBox d'une application


Sujet :

MFC

  1. #1
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut Surveiller une TextBox d'une application
    Bonjour !

    J'ai besoin de surveiller l'évolution de données affichées par une application que je ne peux pas modifier.

    Heureusement pour moi, ces données se retrouvent dans des contrôles "normaux". J'ai en effet pu les retrouver grâce au logiciel SysExporter.

    J'aimerais maintenant pouvoir développer moi-même une toute petite application avec VC++6 se contentant juste de récupérer les contrôles que j'ai besoin de récupérer, et ceci de manière automatisée.

    Je me retrouve hélas confronté à deux problèmes :

    - le premier : je n'arrive pas à trouver quelles fonctions il me faudrait utiliser dans la msdn, et je n'ai en fait aucune idée du processus qu'il me faudrait suivre pour récupérer ces données... Trouver la fenêtre, le handle vers le texte... ?

    - le second : sur certaines machines, qui n'ont pas de différence fondamentale visible, SysExporter n'arrive pas à récupérer le TextBox, alors que sur d'autres il y arrive... Auriez-vous des pistes expliquant ce phénomène ? Peut-être ne serais-je pas concerné avec mon application propre, mais comme SysExporter rencontre ces difficultés, je ne serai pas étonné de les rencontrer moi aussi...

    Merci d'avance pour vos suggestions, conseils...

  2. #2
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut EnumChildWindow encore ??
    Désolé d'insister, mais d'où vient cette fonction EnumChildWindow ? Pourquoi n'est-elle pas sur la msdn library ? Comment s'utilise-t-elle ? Est-elle disponible dans Visual C++6 ?

    Merci d'avance de m'aider à éclaircir ce point

  3. #3
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    findwindow pour trouver la fenetre
    enumwindows pour enumerer les sous-fenetres

    http://msdn.microsoft.com/library/en...ildwindows.asp

    ou alors, trouver le composant avec spy++ et utiliser directement son identifiant

  4. #4
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut Ah d'accord
    Merci pour le lien...

    En effet, j'aurais jamais deviné que quand on cherche "EnumChildWindow", la msdn ne pense pas à citer "EnumChildWindows"... Et comme vous citiez toujours "EnumChildWindow", je me suis fait avoir...

    Merci encore en tout cas, je vais tester ça alors maintenant :-)

  5. #5
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut Mais ça marche comment ce machin ???
    Bonjour !

    Comme le dit le titre, je suis un peu perplexe... :

    Je ne suis absolument pas un habitué de programmation avec les toolkits Win32 et MFC... En fait, à vrai dire je développe presque tout le temps sous Linux...

    Et je dois admettre que leurs fonctions à qui il faut passer des Callbacks en argument & je sais pas trop quoi... Ca me laisse assez perplexe... Et je n'arrive pas à trouver d'exemple simpliste me permettant de comprendre comment ça marche...

    Si vous pouviez me donner quelques pistes, ça serait avec plaisir que je tenterai de suivre vos conseils.

  6. #6
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    regarde cet exemple que je viens de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    HWND hCalc = 0; // control calc
     
    BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam) 
    {
    	if(GetWindowLong(hwndChild, GWL_ID) == lParam)
    	{
    		hCalc = hwndChild;
    		return 0; // trouvé
    	}
    	return 1; // continue enum
    }
     
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    	HWND handleFenCalc = FindWindow(NULL,"Calculatrice");
    	if (!handleFenCalc) 
    		return 0;
    	EnumChildWindows(handleFenCalc,EnumChildProc,(LPARAM)0x193);
     
    	int taille = GetWindowTextLength(hCalc);
    	if (taille)
    	{
    		char *texte = new char[taille+1];
    		GetWindowText(hCalc,texte,taille+1);
    		MessageBox(NULL,texte,"contenu de la calculatrice",MB_ICONSTOP);
    	}
    	return 0;
    }
    il permet de connaitre le texte de la calculatrice (si celle-ci est lancée bien sur).

    je recherche la fenetre avec FindWindow, ensuite j'énumere les sous-fenetres (donc les controles), dès que je trouve le controle qui m'interesse, je sors et je récupere son texte

    NB : Je trouve l'identifiant du controle grace à spy++ (ici 0x193)

  7. #7
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut Ouais, ça marche !!! ... presque
    D'abord, merci pour les informations, ça m'a bien aidé et je commence à avoir un truc qui marche presque maintenant...

    Par contre, il me reste encore quelques légères subtilités à trouver :

    La première chose : le titre de l'application est en partie dynamique, j'entends par là que la fenêtre s'appelle sous la forme : "Motif fixe - Champs Variable". L'idéal serait donc que je puisse passer un paramètre du genre "Motif fixe*" à FindWindow, sauf qu'évidemment, ça serait trop beau si ça avait voulu marcher... Y a-t-il une solution ? En passant d'ailleurs, si la solution pouvait aussi me permettre de récupérer facilement le champs variable de la barre du titre, je vous en serai très reconnaissant.

    Deuxième chose : est-ce que vous auriez la moindre idée expliquant que ça ne marche pas avec la Calculatrice sur le poste XP où j'ai testé, mais que ça marche sur un poste NT à côté ?


    Merci d'avance

  8. #8
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    si le titre de l'application est dynamique, tu peux peut-etre t'en sortir avec l'autre parametre de findwindow, c'est à dire le class name. Maintenant, si c'est un programme VB ou MFC, le nom des class est souvent le meme. Sinon, il suffit de faire un enumWindows, pour énumérer toutes les fenetres, et de comparer le titre avec ta partie fixe.

    ensuite, si ca ne marche pas sous XP, c'est soit que le titre n'est pas le bon (en anglais par exemple), soit que l'identifiant du controle n'est pas le meme (reprogrammation)

  9. #9
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    pour l'énumération, comme j'ai déjà fait un truc du genre, je te mets un exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    BOOL CALLBACK fonctionEnumerationFenetre(HWND hwnd, LPARAM lParam)
    {
    	int taille = GetWindowTextLength(hwnd);
    	if (taille)
    	{
    		char *texte = new char[taille+1];
    		char comp[] = "mon titre à trouver";
    		int siz = GetWindowText(hwnd,texte,taille+1);
    		if (strlen(texte)>strlen(comp))
    		{
    			texte = texte + siz - strlen(comp);
    			if (strcmp(texte,comp)==0)
    				// trouvé
    		}
    	}
    	return 1;
    }
     
    EnumWindows(fonctionEnumerationFenetre,0);

  10. #10
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut La dernière et j'arrête !!
    Merci pour les précisions...

    J'ai pas l'application sous la main, mais je n'aurai pas accès à Internet quand je pourrai tester, donc je ne pourrai plus venir appeler au secours... Et je sens bien le coup du type de classe trop courant, juste pour me faire ch...

    Donc j'en arrive à la question suivante : comment est-ce qu'on utilise enumWindows ? Ca doit sans doute être assez prôche de l'utilisation de EnumChildWindows, mais j'avoue ne pas avoir bien saisi l'histoire des callbacks... Si vous pouvez m'indiquer la procédure type...

    Merci d'avance

  11. #11
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    regarde juste au dessus

  12. #12
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut Merci !!
    Désolé, jsuis forcé d'utiliser un navigateur pas doué... J'ai nommé Internet Explorer pour ne pas le citer... Et il avait pas vidé son cache ou bien rafraîchi, j'en sais rien...

    'fin merci beaucoup en tout cas :-)

  13. #13
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut C'est pas encore ça
    Salut !

    Bon, ça marche avec un programme de simulation que j'ai fait, mais pas avec le vrai programme...

    Ce qui est vachement pratique, c'est que le vrai programme n'est pas sur mon poste de développement et son poste ne dispose pas d'outils de debugs, ni de compilateur...

    Ca a pas l'air d'être un champ edit tout à fait normal, donc je vous mets un lien qui je l'espère pourra vous montrer une capture d'écran de Spy++ sur laquelle j'ai mis en évidence l'élément que je voudrais arriver à catcher...



    Actuellement, ça foire avec un GetWindowTextLength qui vaut 0...

    J'espère que vous pourrez m'aider, et vous remercie d'avance

  14. #14
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    Salut,

    2 choses

    tu peux rajouter un test avant le GetWindowTextLength pour savoir si l'edit a bien été trouvé

    Est-ce que tu as bien passé en paramètre à EnumChildWindows la valeur du control que je crois observer sur ton image, à savoir 0x7023E ?

  15. #15
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut
    Oui, j'ai bien mis "0x7023"...

    Je ne suis pas tout à fait sûr de bien tout comprendre à mon code tout d'un coup...

    Enfin, disons que pour moi, le 0x7023 n'est pas une fenêtre, donc je ne vois pas pourquoi je devrais tester avec IsWindow...

    Enfin bon, ça marche sur mon simulateur, donc ça doit sans doute être logique...

    Tests à l'appui, le IsWindow retourne vrai tant sur le simulateur que sur le vrai logiciel... Une autre idée ?

    Merci d'avance

  16. #16
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    le isWindow retourne vrai car le controle est aussi une fenetre. Le but de ce test étant de vérifier que la fonction d'énumération aboutit correctement.

    Peut-on voir le contenu de l'onglet "class" ?

  17. #17
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut pompompom
    Qu'est-ce que je m'éclate à perdre 20 minutes en déplacement entre l'ordi de dév. et l'ordi de test....

    Bon, donc, cette capture d'écran :



    J'espère que ça pourra vous inspirer :-)

    Merci encore et d'avance

  18. #18
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    d'après le class name (WindowsForms10.EDIT.app3), on peut en déduire que c'est une appli faite avec VB.Net. Et dans la mesure où il n'y a pas d'éditeur de ressources avec ce genre d'applications, et bien, les ID ne sont pas fixes malheureusement. Ce qui fait que la méthode d'utiliser l'ID pour les retrouver ne peut pas marcher (création dynamique) !

    Il te faut donc utiliser une autre méthode ; par exemple, boucler sur le nom de la classe.
    Dans l'enumChildWindows, tu remplaces par quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	char nomDeLaClasse[200];
    	if (GetClassName(hwndChild,nomDeLaClasse,200))
    	{
    		if (strcmp(nomDeLaClasse,"WindowsForms10.EDIT.app3")==0)
    		{
    			hCalc = hwndChild;
    			return 0;
    		}
     
    	}
    	return 1; // continue enum

  19. #19
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut Pas mieux
    J'ai tenté la manip...

    Mais visiblement ils sont plusieurs à avoir le même classname...

    Pis ils disent tous que leur texte est de longueur 0...

    Comment puis-je repérer mon contrôle dans la masse ? Comment accéder à son contenu ?

    // mon royaume pour un point d'entrée dcop à la KDE :-P

  20. #20
    Membre actif
    Inscrit en
    Août 2005
    Messages
    59
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 59
    Par défaut Précision
    De plus, l'id étant tout de même resté identique car je n'ai pas relancé l'application, le GetWindowTextLength retourne toujours 0...

    Je crois que je ne dois pas utiliser la bonne méthode, c'est pas possible ! :-/

    Je mets mon code complet en annexe pour vérifier si ça vous semble cohérent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    #include <windows.h>
    #include <stdio.h>
     
    //#define HANDLE_VAL 0x0000FFFF
    #define HANDLE_VAL 0x0007023E
    #define CLASS_NAME "WindowsForms10.EDIT.app3"
    #define APP_TITLE_BASE "Application Machin"
    #define TAILLE_SAUT_NOM_APP 3
    #define MAX_TEXT	255
    #define MAX_SIZE_HOSTNAME 25
     
    HWND handleFenApp = 0; // App 
    HWND hApp = 0; // control app
    char szConfig[MAX_TEXT];
     
    BOOL CALLBACK fonctionEnumerationFenetre(HWND hwnd, LPARAM lParam)
    {
       int taille = GetWindowTextLength(hwnd);
       if (taille)
       {
          char *texte = new char[taille+1];
    	  char *szFinTexte = new char[taille+1];
          char comp[] = APP_TITLE_BASE;
          int siz = GetWindowText(hwnd,texte,taille+1);
          if (strlen(texte)>strlen(comp))
          {
    		 strcpy (szFinTexte, &texte[strlen(comp)+TAILLE_SAUT_NOM_APP]);
    		 texte[strlen(comp)] = '\0';
     
             if (strcmp(texte,comp)==0)
    		 {
    			handleFenApp = hwnd; 
    			strcpy (szConfig, szFinTexte);
    			delete [] texte;
    			delete [] szFinTexte;
    			return 0;
    		 }
    		 	delete [] texte;
    			delete [] szFinTexte;
          }
       }
       return 1;
    }
     
     
    BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
    {
    	char szNomClasse [MAX_TEXT];
    	if (GetClassName(hwndChild, szNomClasse, MAX_TEXT))
    	{
    		if (strcmp (szNomClasse, CLASS_NAME))
    		{
    			hApp = hwndChild;
    			return 0; // trouvé
    		}
        }
        return 1; // continue enum*/
     
    /*   if(GetWindowLong(hwndChild, GWL_ID) == lParam)
       {
          hApp = hwndChild;
          return 0; // trouvé
       }
       return 1; // continue enum*/
    }
     
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    	EnumWindows(fonctionEnumerationFenetre,0); 
    MessageBox(NULL,"EnumWindows","DBG",MB_ICONSTOP);
    	if (!handleFenApp)
    		return 0;
    	EnumChildWindows(handleFenApp,EnumChildProc,(LPARAM)HANDLE_VAL);
    MessageBox(NULL,"EnumChildWindows","DBG",MB_ICONSTOP);
    	if (IsWindow (hApp))
    	{
    		int taille = GetWindowTextLength(hApp);
    MessageBox(NULL,"GetWindowTextLength","DBG",MB_ICONSTOP);
    char szDebug[255];
    sprintf (szDebug, "handle : %x\ntaille : %d", hApp, taille);
    MessageBox(NULL,szDebug,"DBG",MB_ICONSTOP);
    		if (taille)
    		{
    			char *texte = new char[taille+1];
    			GetWindowText(hApp,texte,taille+1);
    MessageBox(NULL,"GetWindowText","DBG",MB_ICONSTOP);
    			char szMessage [MAX_TEXT];
    			char szHostName [MAX_SIZE_HOSTNAME];
    			unsigned long ulSizeHostName = MAX_SIZE_HOSTNAME;
    			GetComputerName(szHostName, &ulSizeHostName);
     
    			sprintf (szMessage, "%s|020001 (.ini)|SIPLACE (.ini)|%s|%s|le nombre de composants (facult)|date julienne", szHostName, texte, szConfig);
    			MessageBox(NULL,szMessage,"Output",MB_ICONSTOP);
    			delete [] texte;
    		}
    	}
    	else
    		MessageBox(NULL,"IsWindow pas content","DBG",MB_ICONSTOP);
    	return 0;
    }
    Désolé pour tous les MessageBox non indentés, ce sont les éléments que j'ai dû rajouter à défaut de debugger sur la cible...

    J'espère que ceci vous inspirera :-)

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 1
    Dernier message: 13/04/2015, 11h17
  2. Réponses: 2
    Dernier message: 31/10/2011, 11h45
  3. Bind d'une textbox d'une usercontrol sur une Dependency property
    Par Yogy dans le forum Windows Presentation Foundation
    Réponses: 11
    Dernier message: 27/04/2010, 05h26
  4. Pb copier une valeur d'une textbox vers une cellule
    Par whykiki dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 09/12/2007, 11h49
  5. Réponses: 2
    Dernier message: 18/12/2006, 19h04

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