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

RLAPT 32 Messages postés lundi 11 avril 2011Date d'inscription 14 mars 2018 Dernière intervention - 14 sept. 2017 à 11:29 - Dernière réponse : cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention
- 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 

9 réponses

Répondre au sujet
cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention - 15 sept. 2017 à 16:45
+2
Utile
2
Bonjour,

Voir ceci si cela te convient:

http://codes-sources.commentcamarche.net/source/102159-recuperer-des-infos-d-une-fenetre-ouverte
Cette réponse vous a-t-elle aidé ?  
RLAPT 32 Messages postés lundi 11 avril 2011Date d'inscription 14 mars 2018 Dernière intervention - 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
cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention - 19 sept. 2017 à 15:44
Commenter la réponse de cs_Le Pivert
RLAPT 32 Messages postés lundi 11 avril 2011Date d'inscription 14 mars 2018 Dernière intervention - 16 sept. 2017 à 09:49
0
Utile
5
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
cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention - 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
RLAPT 32 Messages postés lundi 11 avril 2011Date d'inscription 14 mars 2018 Dernière intervention > cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention - 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.
cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention > RLAPT 32 Messages postés lundi 11 avril 2011Date d'inscription 14 mars 2018 Dernière intervention - 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
cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention > cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention - 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à
cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention > cs_Le Pivert 5065 Messages postés jeudi 13 septembre 2007Date d'inscriptionContributeurStatut 13 avril 2018 Dernière intervention - 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.