begin process at 2008 05 16 20:56:36
1 173 724 membres
533 nouveaux aujourd'hui
13 972 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

LIRE LE CONTENU DE CONTRÔLES TEXTBOX, RICHEDIT,... D'AUTRES APPLIS WINDOWS


Information sur la source

Catégorie :API Source .NET ( DotNet ) Classé sous : sendmessage, findwindowex, getcontroltext, applications Niveau : Débutant Date de création : 07/12/2003 Date de mise à jour : 08/12/2003 00:09:45 Vu / téléchargé: 11 793 / 492

Note :
10 / 10 - par 4 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (12)
Ajouter un commentaire et/ou une note

Description

Il est parfois important de communiquer entre Managé (C# et CLR) et non Managé (C++ et Win32).
Si vous devez récupérer automatiquement des données qui sont renseignées dans une application Windows extérieure, voici une technique à base de PInvoke

Le StringBuilder est très important !
essayez de décommenter la ligne de #define
ce qui provoque le remplacement des "StringBuilder" par des "string" dans la déclaration et l'appel de GetControlText
Que se passe t-il ?
Nous initialisons une zone 'string' avec des 0. Dans l'exécution de la fonction GetControlText, il y modification de la valeur du string... et la runtime alloue un nouvel emplacement pour ce string. Notre ancienne variable pointe toujours sur la zone initialisée avec nos zeros. Il est donc extrèmement important d'utiliser le StringBuilder qui lui est modifiable (méthode Append)

Source

  • //Faire un projet "Console" et copier ceci
  • //#define STRING // ligne à décommenter pour STRING, à commenter pour STRINGBUILDER
  • using System;
  • using System.Runtime.InteropServices;
  • using System.Text;//pour le StringBuilder
  • class Test
  • {
  • private const int WM_GETTEXTLENGTH = 14;//pour utilisation de SendMessage
  • private const int WM_GETTEXT = 13;//pour utilisation de SendMessage
  • [DllImport("user32.dll", EntryPoint="FindWindowEx")]
  • public static extern int FindWindowEx (
  • int hwndParent, int hwndEnfant, int lpClasse, string lpTitre);
  • [DllImport("user32.dll", EntryPoint="SendMessage")]
  • public static extern int SendMessage (
  • int hwnd, uint wMsg, int wParam, int lParam);
  • [DllImport("user32.dll", EntryPoint="SendMessage")]
  • public static extern int GetControlText ( //renommée pour spécialisation du dernier param
  • #if STRING
  • int hwnd, uint wMsg, int wParam, string lParam);//lParam : récupération du texte
  • #else
  • int hwnd, uint wMsg, int wParam, StringBuilder lParam);//lParam : récupération du texte
  • #endif
  • static void Main(string[] args)
  • {
  • Console.WriteLine("titre de la fenetre a scanner");
  • string titre = Console.ReadLine();
  • int hwnd = FindWindowEx(0, 0, 0, titre);
  • if (hwnd==0) {Console.WriteLine("Erreur, fenêtre non trouvée"); return ;}
  • Console.WriteLine("hwnd Parent = {0}",hwnd);
  • Console.WriteLine("Liste des contrôles enfants:");
  • int hwndEnfant=FindWindowEx(hwnd, 0, 0, null);
  • while (hwndEnfant!=0)
  • {
  • int lgTexte = SendMessage(hwndEnfant, WM_GETTEXTLENGTH, 0, 0) + 1;
  • #if STRING
  • string sbTitre = new string('0',lgTexte);
  • #else
  • StringBuilder sbTitre = new StringBuilder(lgTexte);
  • #endif
  • GetControlText(hwndEnfant, WM_GETTEXT, lgTexte, sbTitre);
  • Console.WriteLine("hwnd={0} => {1}", hwndEnfant, sbTitre);
  • hwndEnfant=FindWindowEx(hwnd, hwndEnfant, 0, null);
  • }
  • Console.WriteLine("Tapez sur une touche...");
  • Console.Read();
  • }
  • }
//Faire un projet "Console" et copier ceci

//#define STRING // ligne à décommenter pour STRING, à commenter pour STRINGBUILDER

using System;
using System.Runtime.InteropServices;
using System.Text;//pour le StringBuilder

class Test
{
	private const int WM_GETTEXTLENGTH = 14;//pour utilisation de SendMessage
	private const int WM_GETTEXT = 13;//pour utilisation de SendMessage
	
	[DllImport("user32.dll", EntryPoint="FindWindowEx")]
	public static extern int FindWindowEx ( 
		int hwndParent,	int hwndEnfant,	int lpClasse, string lpTitre);
	[DllImport("user32.dll", EntryPoint="SendMessage")]
	public static extern int SendMessage (
		int hwnd, uint wMsg, int wParam, int lParam);
	[DllImport("user32.dll", EntryPoint="SendMessage")]
	public static extern int GetControlText ( //renommée pour spécialisation du dernier param
#if STRING
		int hwnd, uint wMsg, int wParam, string lParam);//lParam : récupération du texte
#else
		int hwnd, uint wMsg, int wParam, StringBuilder lParam);//lParam : récupération du texte
#endif

	static void Main(string[] args)
	{
		Console.WriteLine("titre de la fenetre a scanner");
		string titre = Console.ReadLine();
		int hwnd = FindWindowEx(0, 0, 0, titre);
		if (hwnd==0) {Console.WriteLine("Erreur, fenêtre non trouvée"); return ;}
		Console.WriteLine("hwnd Parent = {0}",hwnd);
		Console.WriteLine("Liste des contrôles enfants:");

		int hwndEnfant=FindWindowEx(hwnd, 0, 0, null);
		while (hwndEnfant!=0)
		{
			int lgTexte = SendMessage(hwndEnfant, WM_GETTEXTLENGTH, 0, 0) + 1; 
#if STRING
			string sbTitre = new string('0',lgTexte);
#else
			StringBuilder sbTitre = new StringBuilder(lgTexte);
#endif
			GetControlText(hwndEnfant, WM_GETTEXT, lgTexte, sbTitre);
			Console.WriteLine("hwnd={0} => {1}", hwndEnfant, sbTitre);
			hwndEnfant=FindWindowEx(hwnd, hwndEnfant, 0, null);
		}
		Console.WriteLine("Tapez sur une touche...");
		Console.Read();
	}
}

Conclusion

code fourni avec une boite de dialogue (MFC) de test comportant en particulier un richedit

modification : la première version codait en dur une taille max de 255 caractères pour le texte récupéré. Cette version s'affranchit de cette limite
Elle appelle deux fois SendMessage :
une pour déterminer la longueur
l'autre pour charger le texte

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de tomate69 le 09/12/2003 10:11:06

    Grandiose !
    Sans vouloir etre trop gourmand,  est-il possible dans le même esprit de modifier le contenu d'un des controles de la fenetre ?

  • signaler à un administrateur
    Commentaire de vieuxLion le 09/12/2003 16:53:34

    oui, c'est encore plus simple car il n'a a pas besoin d'utiliser le StringBuilder

    utilise le WM_SETTEXT
    puis la surcharge suivante
        public static extern int GetControlText ( int hwnd, uint wMsg, int wParam, string lParam);
    ou tu mets ton nouveau contenu dans lparam.

  • signaler à un administrateur
    Commentaire de tomate69 le 11/12/2003 09:52:18

    Impeccable ! C'est très drôle, et même si je n'ai pas encore d'idée d'application (En SETTEXT et GETTEXT), je sens que je ne vais pas tarder à en trouver !

    Merci, et bravo pour tout vos codes.

  • signaler à un administrateur
    Commentaire de gg00xiv le 14/12/2003 13:22:23

    Très interessant :) 10/10

  • signaler à un administrateur
    Commentaire de plopman le 12/05/2004 18:30:41

    sympa ...
    Mercii
    10/10
    PlOpmAn

  • signaler à un administrateur
    Commentaire de vdeng le 14/10/2004 23:29:07

    Surprenant !
    Permet de récupérer du texte !
    Dans certaine situation, combiner avec la commande SendKeys !!!

  • signaler à un administrateur
    Commentaire de nico23 le 20/05/2005 14:44:50

    Salut, cool le source, mais autrement si je veux écrire dans une application Windows ( par exemple la fenêtre active du bureau )? en écrivant dans la barre de titre par exemple ?

    Merci de bien vouloir me guider .

  • signaler à un administrateur
    Commentaire de DjAdes le 20/08/2005 10:08:39

    Bonjour,
    Tout d'abord bravo pour cette source et le zip complet.

    J'ai essayé la méthode SETTEXT mais je bloque. Comme WM_GETTEXT, WM_SETTEXT doit être défini avec une valeur, quelle est cette valeur ?

    Une deuxième chose, en regardant dans la documentation MSDN, je me suis rendu compte qu'ils utilisent WM_SETTEXT dans la méthode SendMessage() et pas GetControlText(). Qu'en est-il exactement ?

    Merci d'avance pour vos réponses,
    A bientôt,
    Seb.

  • signaler à un administrateur
    Commentaire de nanomachine2006 le 07/02/2006 11:16:32

    la valeur de WM_SETTEXT=12
    exemple:
    private const int WM_SETTEXT = 12;
    reponse a la deuxieme question:
    GetControlText() c'est un allias de SendMessage(); tu peux le renommer bon te semble.
    pour envoyer le text a une fenetre:
    [DllImport("user32.dll", EntryPoint = "SendMessage")]
            public static extern int SetControlText( //renommée pour spécialisation du dernier param
    int hwnd, uint wMsg, int wParam, string lParam);//lParam : texte a envoyer dans hwnd
    exemple:
    SetControlText(hwnd, WM_SETTEXT, 0, tontext);

  • signaler à un administrateur
    Commentaire de DjAdes le 28/02/2006 16:48:16

    Merci pour cette réponse.

    A bientôt,
    Seb.

  • signaler à un administrateur
    Commentaire de stephanemo le 19/01/2007 14:40:14

    Ce source est vraiment ce que je recherchais, par contre je n'arrive pas à récupérer les controles qui sont à l'intérieur d'un conteneur de type groupbox et du coup je suis bloqué.
    Merci d'avance pour vos réponses
    Steph

  • signaler à un administrateur
    Commentaire de stephanemo le 19/01/2007 16:30:34

    Je me suis débrouillé, en fait il faut juste dire que le parent c'est le groupbox et faire donc un truc récursif...

    Par contre, comment faire pour que ça marche avec des fenêtres à l'intérieur de la fenêtre principale (MDI)?là je vois pas...

    Merci.

    Steph

Ajouter un commentaire

Discussions en rapport avec ce code source

Appels d'offres

Pub



Snippets en rapport

CalendriCode

Mai 2008
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS