Récupérer les infos sur les controles d'une fenêtre externe

Messages postés
37
Date d'inscription
lundi 11 avril 2011
Dernière intervention
1 novembre 2018
- 14 sept. 2017 à 11:29 - Dernière réponse :
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
- 19 sept. 2017 à 15:44
Bonjour,

En recherchant sur le net j'ai réussi à obtenir le Handle d'une fenêtre externe à mon application.

Je butte maintenant pour trouver les informations concernant les contrôles contenus dans cette fenêtre externe. En fait, je voudrais pouvoir récupérer et charger les valeurs de ces contrôles à partir de mon application.

Avez-vous une idée de la méthode pour réaliser cette fonction et quels sont les API à utiliser ?

Merci par avance.

Cordialement.
Afficher la suite 

Votre réponse

9 réponses

Meilleure réponse
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
- 15 sept. 2017 à 16:45
2
Merci

Merci cs_Le Pivert 2

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 87 internautes ce mois-ci

Messages postés
37
Date d'inscription
lundi 11 avril 2011
Dernière intervention
1 novembre 2018
- 15 sept. 2017 à 18:43
Merci,
Je n'ai pas encore chargé le projet, mais à la lecture de l'intro, ça ressemble assez bien à ce que je recherche.

Je me penche dessus aussitôt que possible.

Cordialement
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
- 19 sept. 2017 à 15:44
Commenter la réponse de cs_Le Pivert
Messages postés
37
Date d'inscription
lundi 11 avril 2011
Dernière intervention
1 novembre 2018
- 16 sept. 2017 à 09:49
0
Merci
Bonjour,

Je reviens sur le sujet. L'application proposée par cs_Le Pivert est super, mais en fait ce n'est pas exactement ce que je souhaite.

En effet, je souhaite récupérer tous les éléments d'une fenêtre à partir de son handle et pouvoir les manipuler (faire de la récupération de données et du remplissage d'information à partir de mon application).

Y a t'il une ou plusieurs API qui à partir du handle d'une fenêtre permet de :

- Récupérer tous les éléments de la fenêtre.
- Une fois fait accéder à leurs propriétés et leurs méthode.


Pouvez-vous m'indiquer un fil conducteur.

Merci d'avance à tous
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
- 16 sept. 2017 à 11:50
Voici un exemple pour le titre et le redimensionnement de la fenêtre qui fonctionne:

http://codes-sources.commentcamarche.net/forum/affich-10041058-lancer-un-exe-et-le-redimensionner#11

Et celui-ci pour les controls que je n'ai pas réussi à faire fonctionner. Tu auras peut-être plus de chance que moi!

http://codes-sources.commentcamarche.net/forum/affich-10022830-handle-d-un-controle-d-une-fenetre-externe#11

@+ Le Pivert
Messages postés
37
Date d'inscription
lundi 11 avril 2011
Dernière intervention
1 novembre 2018
>
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
- 16 sept. 2017 à 12:49
Merci encore du temps passé pour m'aider.

Le premier exemple est déjà fait dans mon application, lorsque je récupère le Handle de la fenêtre qui m'intéresse, je rétréci la dite fenêtre. Mais avant j'aimerai récupérer les infos de certains contrôles contenus dans cette fenêtre.
Pour le deuxième,il faut que j'analyse.

Merci encore.
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
>
Messages postés
37
Date d'inscription
lundi 11 avril 2011
Dernière intervention
1 novembre 2018
- 17 sept. 2017 à 18:09
J'ai finalement réussi à adapter le dernier code avec un autre code trouvé sur le net:

Option Strict On
Imports System.Runtime.InteropServices
Public Class Form1
    ' http://www.pinvoke.net/default.aspx/user32.enumchildwindows
    <DllImport("User32.dll")> _
    Private Shared Function EnumChildWindows _
     (ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, _
     ByVal lParam As IntPtr) As Boolean
    End Function
    Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
    Public Shared Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
        Dim ChildrenList As New List(Of IntPtr)
        Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
        Try
            EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
        Finally
            If ListHandle.IsAllocated Then ListHandle.Free()
        End Try
        Return ChildrenList.ToArray
    End Function
    Private Shared Function EnumWindow(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
        Dim ChildrenList As List(Of IntPtr) = CType(GCHandle.FromIntPtr(Parameter).Target, Global.System.Collections.Generic.List(Of Global.System.IntPtr))
        If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
        ChildrenList.Add(Handle)
        Return True
    End Function
    ' http://codes-sources.commentcamarche.net/forum/affich-10022830-handle-d-un-controle-d-une-fenetre-externe#11
    Private Const WM_GETTEXT As Integer = &HD
    Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, _
    ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        For Each p As Process In Process.GetProcesses
            If p.MainWindowTitle.Contains("Assistant photos") Then ' adapter le titre de la fenêtre
                Dim Childrens As IntPtr() = GetChildWindows(p.MainWindowHandle)
                Dim Handle As IntPtr = Marshal.AllocHGlobal(100)
                'Dans mon cas, PositionDuContrôle=10
                Dim NumText As Integer = CInt(SendMessage(Childrens(10), WM_GETTEXT, CType(50, IntPtr), Handle))
                'Récupération du texte du contrôle!
                MsgBox(Marshal.PtrToStringUni(Handle))
            End If
        Next
        End Sub
End Class


J'ai mis les 2 liens

@+ Le Pivert
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
>
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
- 17 sept. 2017 à 21:07
Je viens de penser à faire une boucle sur tous les controls comme ceci:

 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Try
            For Each p As Process In Process.GetProcesses
                If p.MainWindowTitle.Contains("Assistant photos") Then ' adapter le titre de la fenêtre
                    Dim Childrens As IntPtr() = GetChildWindows(p.MainWindowHandle)
                    Dim Handle As IntPtr = Marshal.AllocHGlobal(100)
                    For i = 1 To 30 'a adapter au nombre de controls
                        'Dans mon cas, PositionDuContrôle=10
                        Dim NumText As Integer = CInt(SendMessage(Childrens(i), WM_GETTEXT, CType(50, IntPtr), Handle))
                        'Récupération du texte du contrôle!
                        ListBox1.Items.Add(Marshal.PtrToStringUni(Handle))
                    Next
                End If
            Next
        Catch
        End Try
    End Sub


il suffit d'ajouter une Listbox pour afficher les textes.
J'ai mis un Try catch pour éviter le bug quand on ne connait pas le nombre de controls

Voilà
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
>
Messages postés
5530
Date d'inscription
jeudi 13 septembre 2007
Statut
Contributeur
Dernière intervention
17 novembre 2018
- 18 sept. 2017 à 08:37
Je me suis amusé à faire un programme,

2 listBox nommées:

lstappli et lstcontrol

2 buttons nommés:

cmdcontrol et cmdappli
mettre cmdcontrol.Enabled = False

et un label:

lblcontrol

voici le code:

Option Strict On
Imports System.Runtime.InteropServices
Public Class Form1
    ' http://www.pinvoke.net/default.aspx/user32.enumchildwindows
    <DllImport("User32.dll")> _
    Private Shared Function EnumChildWindows _
     (ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, _
     ByVal lParam As IntPtr) As Boolean
    End Function
    Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
    Public Shared Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
        Dim ChildrenList As New List(Of IntPtr)
        Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
        Try
            EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
        Finally
            If ListHandle.IsAllocated Then ListHandle.Free()
        End Try
        Return ChildrenList.ToArray
    End Function
    Private Shared Function EnumWindow(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
        Dim ChildrenList As List(Of IntPtr) = CType(GCHandle.FromIntPtr(Parameter).Target, Global.System.Collections.Generic.List(Of Global.System.IntPtr))
        If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
        ChildrenList.Add(Handle)
        Return True
    End Function
    ' http://codes-sources.commentcamarche.net/forum/affich-10022830-handle-d-un-controle-d-une-fenetre-externe#11
    Private Const WM_GETTEXT As Integer = &HD
    Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, _
    ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
    Dim nomappli As String
    Private Sub cmdcontrol_Click(sender As System.Object, e As System.EventArgs) Handles cmdcontrol.Click
        Try
            For Each p As Process In Process.GetProcesses
                If p.MainWindowTitle.Contains(nomappli) Then
                    Dim Childrens As IntPtr() = GetChildWindows(p.MainWindowHandle)
                    Dim Handle As IntPtr = Marshal.AllocHGlobal(100)
                    For i As Integer = 1 To Childrens.Length
                        Dim NumText As Integer = CInt(SendMessage(Childrens(i), WM_GETTEXT, CType(50, IntPtr), Handle))
                        'Récupération du texte du contrôle!
                        lstcontrol.Items.Add(i & "    " & Marshal.PtrToStringUni(Handle))
                    Next
                End If
            Next
        Catch
        End Try
        lblcontrol.Text = CStr(lstcontrol.Items.Count) & " controls"
    End Sub
    Private Sub cmdappli_Click(sender As System.Object, e As System.EventArgs) Handles cmdappli.Click
        lstappli.Items.Clear()
        cmdcontrol.Enabled = False
        For Each p As Process In Process.GetProcesses
            If Len(Trim(p.MainWindowTitle)) > 0 Then lstappli.Items.Add(p.MainWindowTitle)
        Next p
    End Sub
    Private Sub lstappli_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles lstappli.SelectedIndexChanged
        nomappli = CStr(lstappli.SelectedItem) 'affiche le nom de l'application
        cmdcontrol.Enabled = True
    End Sub
End Class


Bonne programmation
Commenter la réponse de RLAPT

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.