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

Soyez le premier à donner votre avis sur cette source.

Vue 19 721 fois - Téléchargée 789 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

Messages postés
100
Date d'inscription
jeudi 3 mars 2005
Statut
Membre
Dernière intervention
24 mai 2013

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
Messages postés
7
Date d'inscription
jeudi 10 avril 2003
Statut
Membre
Dernière intervention
3 février 2004

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
Messages postés
7
Date d'inscription
jeudi 10 avril 2003
Statut
Membre
Dernière intervention
3 février 2004

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
Messages postés
38
Date d'inscription
vendredi 31 mai 2002
Statut
Membre
Dernière intervention
6 juillet 2011

Merci pour cette réponse.

A bientôt,
Seb.
Messages postés
3
Date d'inscription
lundi 7 février 2005
Statut
Membre
Dernière intervention
7 février 2006

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);
Afficher les 13 commentaires

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.