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

RLAPT Messages postés 48 Date d'inscription lundi 11 avril 2011 Statut Membre Dernière intervention 29 avril 2020 - 14 sept. 2017 à 11:29
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 - 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.

2 réponses

cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137
15 sept. 2017 à 16:45
2
RLAPT Messages postés 48 Date d'inscription lundi 11 avril 2011 Statut Membre Dernière intervention 29 avril 2020
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
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137
19 sept. 2017 à 15:44
0
RLAPT Messages postés 48 Date d'inscription lundi 11 avril 2011 Statut Membre Dernière intervention 29 avril 2020
16 sept. 2017 à 09:49
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
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137
Modifié le 16 sept. 2017 à 12:01
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
0
RLAPT Messages postés 48 Date d'inscription lundi 11 avril 2011 Statut Membre Dernière intervention 29 avril 2020 > cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024
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.
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137 > RLAPT Messages postés 48 Date d'inscription lundi 11 avril 2011 Statut Membre Dernière intervention 29 avril 2020
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
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137 > cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024
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à
0
cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024 137 > cs_Le Pivert Messages postés 7903 Date d'inscription jeudi 13 septembre 2007 Statut Contributeur Dernière intervention 11 mars 2024
Modifié le 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
0
Rejoignez-nous