Lire le contenu de contrôles textbox, richedit,... d'autres applis windows

Soyez le premier à donner votre avis sur cette source.

Vue 20 121 fois - Téléchargée 853 fois

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 / Exemple :


//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

Codes Sources

A voir également

Ajouter un commentaire Commentaires
johnnous Messages postés 100 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 24 mai 2013
25 nov. 2008 à 16:04
Salut
désole je n'arrive pas à faire fonctionner l'exemple je n'ai pas la fenetre dos et je clique sur ok
l'appli s'arrete
stephanemo Messages postés 7 Date d'inscription jeudi 10 avril 2003 Statut Membre Dernière intervention 3 février 2004
19 janv. 2007 à 16:30
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
stephanemo Messages postés 7 Date d'inscription jeudi 10 avril 2003 Statut Membre Dernière intervention 3 février 2004
19 janv. 2007 à 14:40
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
DjAdes Messages postés 38 Date d'inscription vendredi 31 mai 2002 Statut Membre Dernière intervention 6 juillet 2011
28 févr. 2006 à 16:48
Merci pour cette réponse.

A bientôt,
Seb.
nanomachine2006 Messages postés 3 Date d'inscription lundi 7 février 2005 Statut Membre Dernière intervention 7 février 2006
7 févr. 2006 à 11:16
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);

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.