Lire le contenu d'une application tierce

albourg Messages postés 6 Date d'inscription samedi 4 février 2006 Statut Membre Dernière intervention 19 juillet 2011 - 9 juil. 2011 à 17:31
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 - 19 juil. 2011 à 19:17
Bonjour,

j'ai une application fournie avec un matériel électronique qui affiche en contenu des mesures prises en temps réel dans un tableau, 24h sur 24. Cette application est fournie par le constructeur (sans la source), non modifiable.
Je veux écrire une application qui lit ces données toutes les x secondes et m'envoye un e-mail si une valeur atteint un seuil critique.
Malheureusement, l'application fournie avec le matériel électronique ne permet pas de faire un copier-coller du tableau (que j'auvais fait via des sendkeys).
J'aimerais savoir si , à partir du Handle de la fenêtre (que je peux retrouver assez facilement), je peux à partir de access (vba) aller retrouver les contrôles de cette fenêtre et leur contenu. Quelqu'un aurait-il un exemple d'une telle manipulation API?

Merci,
Alain

17 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
9 juil. 2011 à 21:00
Boànjour,

Si (et seulement si) à la fois :
- tu sais extraire le handle du contrôle concerné dans la fenêtre/conteneur concernée
- qu'il s'agit bien d'un contrôle contenant du texte
Tu peux alors extraire son contenu
Ici un exemple pour extraire d'une textbox de ta propre appli son contenu.
On connait dans ce cas le handle de la textbox
Exemple, donc :

Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Private Sub Form_Activate()
    MsgBox extraitcontenucontrole(Text1.hwnd)
End Sub

Private Function extraitcontenucontrole(mhwnd As Long) As String
    extraitcontenucontrole = String(GetWindowTextLength(mhwnd) + 1, Chr$(0))
    GetWindowText mhwnd, extraitcontenucontrole, Len(extraitcontenucontrole)
End Function

Te reste bien évidemment à savoir extraire le handle du contrôle en cause !

____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
9 juil. 2011 à 21:27
Commence déjà par extraire le handle de la fenêtre "conteneur".

Regarde ce que l'on peut par exemple faire, lorsque l'on connaît ce handle (dans l'exemple qui suit : le handle de ton propre Form, que l'on connaît donc) :

Sur un Form : un bouton de commande, deux textboxes nommées Text1 et Text2 et une listbox nommée List1
Code pour ton Form :
Private Sub Form_Activate()
   Text1.Text = "bonjour"
   Text2.Text = "Hello"
   EnumChildWindows Me.hwnd, AddressOf EnumChildProc, ByVal 0&
End Sub

Dans un module.bas :
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
Public Function EnumChildProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
    Dim sSave As String
    sSave = Space$(GetWindowTextLength(hwnd) + 1)
    GetWindowText hwnd, sSave, Len(sSave)
    sSave = Left$(sSave, Len(sSave) - 1)
    If sSave <> "" Then Form1.List1.AddItem sSave
    EnumChildProc = 1
End Function

Lance et regarde ce que tu vois dans la listbox.
Ce n'est qu'un exemple de ce que tu peux chercher à faire avec la fenêtre de l'appli externe



____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
10 juil. 2011 à 10:30
On peut même aller un peu plus loin et même plus simplement.

Regarde par exemple ceci :

Sur un Form : plusieurs controls dont des textbox + une listbox nommée List1 (quui servira à la visualisation du résultat)

Code sur Form :
Option Explicit

Private Sub Form_Activate()
    Set ou_montrer = List1
    Dim retourne As Long, lParam As Long
    Dim le_handle_fenetre As Long
    le_handle_fenetre Me.hwnd '>> le handle de la fenêtre (ici, pour demo, celui de ton Form)
    retourne =  EnumChildWindows(le_handle_fenetre, AddressOf EnumChildProc, lParam)
End Sub


+, dans un module.Bas :
Option Explicit
      Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
         As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long

      Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
         (ByVal hwnd As Long, ByVal lpClassName As String, _
         ByVal nMaxCount As Long) As Long

      Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
         (ByVal hwnd As Long, ByVal lpString As String, _
         ByVal cch As Long) As Long

      Public ou_montrer As ListBox

      Function EnumChildProc(ByVal le_handle_fenetre As Long, ByVal lParam As Long) As Long
         Dim RetVal As Long
         Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
         Dim WinClass As String, WinTitle As String
         Dim WinWidth As Long, WinHeight As Long
         RetVal  = GetClassName(le_handle_fenetre, WinClassBuf, 255)
         WinClass = nettoyage(WinClassBuf)
         RetVal = GetWindowText(le_handle_fenetre, WinTitleBuf, 255)
         WinTitle = nettoyage(WinTitleBuf)
         ou_montrer.AddItem WinClass & "===>> Title = " & WinTitle
         EnumChildProc = True
      End Function

      Public Function nettoyage(chaine As String) As String
         nettoyage = chaine
         If (InStr(chaine, Chr(0)) > 0) Then
            nettoyage = Left(chaine, InStr(chaine, Chr(0)) - 1)
         End If
         If Left(nettoyage, 7) = "Thunder" Then
           nettoyage = Mid(nettoyage, 8)
         End If
      End Function

Lance et regarde ==>> tu as cette fois-ci un peu plus (la classe de chaque contrôle + ce qu'il contient éventuellement)





____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
10 juil. 2011 à 11:13
Je continue à cogiter pour toi ...

Résultat à voix haute de mes cogitations matinales ===>>
Si tu analyses chacun de mes codes plus haut, tu vois que l'énumération passe par celle de chacun des handles des contrôles présents, n'est-ce pas ?
Bien ==>>
Il est également possible, pour chacun de ces handles, de déterminer la position géographique du contrôle (quelques fonctions et structures complémentaires à insérer dans mes codes) ===>> et là, je pense que tu me "vois venir" ===>> si par exemple, les contrôles qui t'intéressent sont placés dans un ordre déterminé (par exemple de haut en bas) sur la fenêtre de ton outil, il suffira de faire une comparaison de positions

Mais je n'irai plus loin (dans l'écriture de ce genre de code) que lorsque tu m'auras confirmé que tu peux extraire le handle de la fenêtre de l'outil concerné. Car ce ne sera le cas que s'il s'agit d'une fenêtre Windows.

J'attends donc ta réponse sur ce point précis et incontournable.


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
albourg Messages postés 6 Date d'inscription samedi 4 février 2006 Statut Membre Dernière intervention 19 juillet 2011
15 juil. 2011 à 23:25
Je sais obtenir le handle de la fenetre et même le nom du type du contrôle "AfxFrameOrView80".

Maintenant comment puis-je "lire" ce contrôle et énumérer ses propriétés...?

Merci,
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
16 juil. 2011 à 07:39
Bien.
Etape 1 :
dans le code d'appel que je t'ai déjà montré :
le_handle_fenetre Me.hwnd '>> le handle de la fenêtre (ici, pour demo, celui de ton Form)

Mets donc le handle de ta fenêtre à la place de Me.hwnd (comme je te l'ai déjà dit)

Etape2 :
dans le code de la fonction :
Function EnumChildProc(ByVal le_handle_fenetre As Long, ByVal lParam As Long) As Long
         Dim RetVal As Long
         Dim WinClassBuf As String * 255, WinTitleBuf As String * 255
         Dim WinClass As String, WinTitle As String
         Dim WinWidth As Long, WinHeight As Long
         RetVal = GetClassName(le_handle_fenetre, WinClassBuf, 255)
         WinClass = nettoyage(WinClassBuf)
         RetVal = GetWindowText(le_handle_fenetre, WinTitleBuf, 255)
         WinTitle = nettoyage(WinTitleBuf)
         ou_montrer.AddItem WinClass & "===>> Title = " & WinTitle
         EnumChildProc = True
 End Function


ajoute une expression conditionnelle pour ne garder que les contrôles de cette classe :
....
         WinClass = nettoyage(WinClassBuf)
         RetVal = GetWindowText(le_handle_fenetre, WinTitleBuf, 255)
         WinTitle = nettoyage(WinTitleBuf)
         If WinClass = ....... (ta classe ..... then
               ou_montrer.AddItem WinClass & "===>> Title = " & WinTitle
         end if
         ....

Et regarde ce que tu as dans ta listbox ===>>
- si vide : tu t'es trompé sur la classe
- si un seul article de cette classe, tu l'as isolé
- si plusieurs articles de cette classe, il va falloir isoler celui qui t'intéresse par comparaison de positions (comme suggéré dans mon message précédent.

Quel cas constates-tu en exécutant ce code ?

____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
albourg Messages postés 6 Date d'inscription samedi 4 février 2006 Statut Membre Dernière intervention 19 juillet 2011
17 juil. 2011 à 10:14
Comme j'ai dit:

Je sais obtenir le handle de la fenetre et même le nom du type du contrôle "AfxFrameOrView80".

Le WinTitle vaut AfxFrameOrView80.

La question est: comment puis-je "lire" ce contrôle et énumérer ses propriétés/valeurs...? J'ai besoin du contenu de la grille.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
17 juil. 2011 à 10:24
et même le nom du type du contrôle "AfxFrameOrView80".

Le WinTitle vaut AfxFrameOrView80.


Sûrement pas !
Tu confonds là type, classe et titre.
____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
albourg Messages postés 6 Date d'inscription samedi 4 février 2006 Statut Membre Dernière intervention 19 juillet 2011
17 juil. 2011 à 17:50
j'ai un #32770, sans titre
J'ai 9 Button
J'ai un contrôle static avec une date, et j'ai 5 TLMCOMCLASS (dont 1 avec un titre "Custom 1")
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
17 juil. 2011 à 18:00
Il est déraisonnable de continuer ainsi cette discussion à l'aide d'expressions telles que "j'ai...".
Je te serais reconnaissant de bien vouloir nous montrer ton code complet, tel qu'il est après ceux que je t'ai montrés
1) le 9 juillet
2) le 10 juillet
3) le 16 juillet
et tous les commentaires (mes messages précédents)


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
17 juil. 2011 à 19:04
Enfin quoi !
- Tu sais (mon tout premier code) comment extraire le contenu d'un contrôle contenant du texte (GetWindowText)
- tu sais (mon deuxième code) énumérer les contrôles "enfants" d'une fenêtre
- tu sais (mon 3ème code) déterminer la classe d'un contrôle
- tu sais (mon 4ème bout de code) dire que tu n'alimentes une listbox que que si le contrôle est d'une classe déterminée.

Que te manque-t-il donc ? ===>>> articuler tout cela, si tu as tout suivi et compris


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
albourg Messages postés 6 Date d'inscription samedi 4 février 2006 Statut Membre Dernière intervention 19 juillet 2011
19 juil. 2011 à 00:41
En fait ca ne marche qu'à moitié

Voici une capture écran des infos à obtenir:


Et voici ce que j'ai fait (n'ayant pas vb, j'ai fait ca en access). Tes fonctions sont incluses dans Module1.
Le formulaire Form1 est composé de 3 x 2 listbox (une visible avec le texte, une invisible avec les handle), d'un bouton et d'un mémo.
Si on clique sur le bouton, la liste des fenêtres visible apparait dans le première listbox.
Si on double clique un item de cette première liste, il remplit la 2e listbox avec les handle de cette fenêtre.

J'ai d'abord mis le code qui prenait le texte d'un contrôle cliqué dans la deuxième liste, sans succès (je peux lire les boutons et l'heure, mais sans plus).
Je me suis alors dit que la grille était peut-être elle-même incluse dans un contrôle
=> Quand on clique sur un contrôle de la 2e liste, on remplit la 3e liste avec les contrôles présents dans le handle cliqué.
Si on double vlique la 3e liste, on remplit le mémo avec le texte du contrôle sélectionné.

Malheureusement, je n'arrive pas à avoir le moindre texte de la grille, ni titres ni valeurs.

J'espère être assez clair.
Alain
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
19 juil. 2011 à 07:25
Et voici ce que j'ai fait (n'ayant pas vb, j'ai fait ca en access). Tes fonctions sont incluses dans Module1.

Bonjour,
Il se trouve que :

- Ta discussion a cependant été ouverte dans la section VB6 !
- Je n'ouvre jamais un fichier exécutable ainsi "déposé"
- Je ne possède d'ailleurs pas Access !


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
19 juil. 2011 à 10:34
Je voudrais (à tout hasard) te rappeler que la fonction GetWindowText te retournera le "contenu" de contrôles "simples" et qui ont un hwnd (boutons de commande, textboxes, par exemple) mais pas celui de composants plus complexes (telles les listboxes, comboboxes, grilles diverses, etc ...).
Tu peux bien sûr envisager également une communication de type OLE AUTOMATION, mais, pour ce faire, il faut qu"'à la fois :
- l'application externe accepte ce type de communication
- tu possèdes un descriptif complet et précis (spécifications techniques) de l'application externe dont il s'agit.
Et seul le concepteur de l'application dont il s'agit peut te répondre sur le premier point et te renseigner sur le second.


____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
albourg Messages postés 6 Date d'inscription samedi 4 février 2006 Statut Membre Dernière intervention 19 juillet 2011
19 juil. 2011 à 19:01
Sorry, mais je n'ai pas vb 6. Si tu veux je peux copier le code des modules. Mais le souci ne se situe pas dans le code actuel.

Le constructeur de l'application me propose de lui payer une somme rondelette pour ajouter un "beep" quand une des valeurs dépasse un intervalle délimité. Moi je veux être prévenu par mail ou par sms quand une des valeurs dépasse un intervalle délimité, d'où ma tentative via programmation de lire le contenu de ce contrôle.
L'application ne permet même pas de copier/coller de ces valeurs, ni même de sélectionner dans la grille. Je ne pense pas que cette application soit prévue pour utiliser l'OLE.
Par contre si je trouvais un moyen de savoir quel est le contrôle "grille" et les méthodes pour en interroger le contenu, ca m'arrangerait.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
19 juil. 2011 à 19:10
Sorry, mais je n'ai pas vb 6.



Accueil > Forum > Visual Basic 6 > Windows > API > Lire le contenu d'une application tierce

où est l'erreur ?
____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
19 juil. 2011 à 19:17
Le constructeur de l'application me propose de lui payer une somme rondelette pour ajouter un "beep" quand une des valeurs dépasse un intervalle délimité. Moi je veux être prévenu par mail ou par sms quand une des valeurs dépasse un intervalle délimité, d'où ma tentative via programmation de lire le contenu de ce contrôle

Bien évidemment, s'il doit passer du temps à intervenir sur son source !
Je ne pense pas que cette application soit prévue pour utiliser l'OLE.

Et je ne vois pourtant personnellement pas d'autre moyen (sauf à aller "fouiller" dans la mémoire (et ce sera plutôt croustillant et hasardeux).
Par contre si je trouvais un moyen de savoir quel est le contrôle "grille" et les méthodes pour en interroger le contenu, ca m'arrangerait.

Si tu trouves ===>> dis-nous et dépose un source !
____________________
Utiliser le bouton "REPONSE ACCEPTEE" sur une réponse exacte facilite les recherches ultérieures d'autres forumeurs. PENSEZ-Y SVP
0
Rejoignez-nous