EXTRAIRE LE TEXTE DES FENETRES D'APPLICATIONS TIERCES (LISTBOX, LISTVIEW, TEXTBO

cs_muad-dib Messages postés 103 Date d'inscription lundi 9 avril 2001 Statut Membre Dernière intervention 16 juillet 2008 - 19 avril 2008 à 23:13
Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 2 septembre 2010 - 4 août 2010 à 10:27
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/46390-extraire-le-texte-des-fenetres-d-applications-tierces-listbox-listview-textboxes

Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 2 septembre 2010
4 août 2010 à 10:27
Ah je me doutais qu'avec ma chance, j'allais tomber sur un truc du style :D
Bien vu pour les lettres p, j'avais pas vu. Merci beaucoup pour le coup de main néanmoins !

Simon
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
4 août 2010 à 09:38
regarde les jambes des deux 'p' du mot 'stopped'
elles sortent du cadre.

en gros, cela veux simplement dire que c'est dessiné par le programme, et donc pas simple a récupérer...
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
4 août 2010 à 09:27
Pour la première zone de texte, tu peux faire :

If sClass = "Afx:400000:0:10013:10:0" Then
nLength = SendMessage(vhWnd, WM_GETTEXTLENGTH, 0, ByVal 0&)
sBuffer = Space$(nLength)
nLength = SendMessage(vhWnd, WM_GETTEXT, nLength, ByVal sBuffer)
vsResult = sBuffer
ExtractWindowText = True
End If

je creuse pour les autres panels
Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 2 septembre 2010
3 août 2010 à 11:55
Merci Renfield,

Je ne m'attendais pas à une réponse aussi rapide !
Il s'agit en fait d'un vieux programme (d'il y a 10 ans je pense) qui controle un petit testeur numérique de labo. Et je cherche à automatiser une séquence de mesure en le pilotant via les API windows. Je ne sais pas où on peut trouver une classe similaire sur un autre soft, mais si j'ai aiguisé ta curiosité, je peux éventuellement te transmettre l'exécutable (il fonctionne en mode démo quand il est tout seul). Mais je posais la question surtout pour savoir si le problème était connu (apparemment, pas si connu que ça) et quelle démarche adopter... La classe exacte retournée par winspector sur la barre de statut est "Afx:400000:0:10011:10:0" (la barre d'outil du soft, elle, est plus classique: ToolbarWindow32).
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
3 août 2010 à 01:06
dans quel soft puis-je trouver une telle status bar ?
Chouchensb Messages postés 64 Date d'inscription jeudi 3 mars 2005 Statut Membre Dernière intervention 2 septembre 2010
2 août 2010 à 23:11
Bonjour Renfield,

j'ai récupéré une partie de ton code pour aller lire le texte d'un élément d'une barre de status (message SB_GETTEXT). Ca marche impeccablement sur une structure de classe msctls_statusbar32 (comme dans les programmes Wordpad ou Paint), mais le hic, c'est que j'ai voulu l'utiliser sur une status bar de classe "afx:400000.... quelquechose" et là, ça ne marche pas. Apparemment, je ne suis pas le seul à avoir eu ce problème (http://www.codeproject.com/Messages/3271576/How-to-read-text-from-a-status-bar-CStatus-of-anot.aspx), aurais-tu la réponse ?
CADRATURE Messages postés 25 Date d'inscription mercredi 26 novembre 2003 Statut Membre Dernière intervention 13 juin 2009
10 janv. 2009 à 00:13
Super
beebopcmoi Messages postés 6 Date d'inscription vendredi 3 novembre 2006 Statut Membre Dernière intervention 23 juillet 2009
5 oct. 2008 à 13:23
oui effectivement, j'ai finalement réussir a extraire le Bold du treeview :) ne déchiffrant qu'a grande peine ton code, j'intervertissais les handles du treeview et de l'item, honte a moi... mais j'avoue que concernant la couleur et l'identifiant de l'icone, je n'obtiens rien... Je pense que le treeview en question a été implémenté par d'autres fonctions, et j'ignore comment lui poser les bonnes questions.... :s
Si jamais tu es interressé par la question, je peux éventuellement te dire ou trouver ce treeview, si tu veux y jeter un oeil un peu plus expérimenté que le mien :) Je suis dispo en messagerie

note : sur chaque item, une infobulle regroupe toutes les informations qui m'intéressent, et j'arrive à lire ces infobulles, mais uniquement lorsqu'ils existent, et ils n'existent que ponctuellement, lorsque ma souris traine dessus... S'il y avait éventuellement une manière de forcer la création de ces bulles, que je puisse les lire....
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
4 oct. 2008 à 18:21
la couleur me semble complexe a obtenir. la reste ca devrait aller
beebopcmoi Messages postés 6 Date d'inscription vendredi 3 novembre 2006 Statut Membre Dernière intervention 23 juillet 2009
2 oct. 2008 à 16:47
J'ai besoin de lire un certain nombre d'informations sur le treeview32 d'une
application externe:
Pour chaque item, je veux connaitre:
- Le texte de l'item
- La couleur de ce texte
- Si le texte est BOLD ou non
- L'icone affichée a coté de l'item

Grace a ce programme,j'ai pu extraire le code qui me donne le résultat suivant :

Racine1
item1
item2
Racine2
item3

Je cherche donc a obtenir un résultat qui donnerait :

Racine1, IsBold, IndexTextColor, IndexIcone
item1, IsBold, IndexTextColor, IndexIcone
item2, IsBold, IndexTextColor, IndexIcone
Racine2, IsBold, IndexTextColor, IndexIcone
item3, IsBold, IndexTextColor, IndexIcone

je ne suis pas un fin connaisseur des allocations mémoires ou du subclassing, et
je ne comprend pas tout aux getitem / getitemstate, TVIF_STATE, TVIS_BOLD et compagnie...
Je pense qu'à partir d'un exemple pour extraire le Bold, j'arriverais a tirer les autres informations, mais j'ai beau avoir bricolé de plusieurs facons, je n'arrive pas a extraire la moindre information supplémentaire

Auriez-vous un exemple d'application? une fonction IsItemBold(...) a rajouter a ce programme?
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
30 sept. 2008 à 05:15
voir la valeur de state, dans les TVITEM.
TVIS_BOLD => controle le gras.

voir ici. http://msdn.microsoft.com/en-us/library/ms913992.aspx
beebopcmoi Messages postés 6 Date d'inscription vendredi 3 novembre 2006 Statut Membre Dernière intervention 23 juillet 2009
29 sept. 2008 à 18:13
Genial :)
Après bien des recherches, enfin un code qui permet d'extraire le contenu d'un treeview... Bravo :)

Sans vouloir abuser... je travaille sur un treeview d'une application externe, qui affiche des textes en couleur et en gras ou non... je cherche un bout de code (en plus) qui me dirait pour chaque item s'il est en gras, en italique, et sa couleur...
C'est possible ca?
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
23 mai 2008 à 16:25
dommage, la ListBox cochable de WindowsUpdate n'est pas supportée :(
cs_AGG Messages postés 46 Date d'inscription jeudi 15 avril 2004 Statut Membre Dernière intervention 9 décembre 2012
4 mai 2008 à 12:56
Excellent !
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 avril 2008 à 16:11
probleme corrigé...

effectivement, la déclaration d'APIs de VirtualFreeEx etait fausse: le parametre Size était passé par référence...
il faut donc lui donner ByVal 0&
ou modifier la déclaration
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
22 avril 2008 à 15:31
Ouf, le problème peut se régler :
Le souci vient de là :

http://www.vbfrance.com/infomsg_VIRTUALFREEEX-SUITE_147596.aspx#1
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 avril 2008 à 15:27
j'ai intégré la gestion des TreeViews
regarde si tu as toujorus le même soucis...
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
22 avril 2008 à 15:13
encore moi ...
après "enquête", j'ai bien l'impression qu'il y a une fuite mémoire.
J'ai essayé avec différents processus (explorateur, taskmanager ...), la mémoire utilisée augmente à chaque requête de ton programme, mais n'est pas libérée apparemment.
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
22 avril 2008 à 14:43
Précision : ça ne fonctionnait plus avec mon explorer
mais en tuant/relançant le process, tout est revenu dans l'ordre (j'ai dû faire des fuites mémoires en débuguant mon bout de code)

Quand on récupère le treeview de l'explorateur, on ne récupère en fait que ce qui a déjà été affiché dans ce treeview.
En clair, on ne récupère pas toute l'arborescence du disque dur, mais seulement les répertoires déjà parcouru.
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
22 avril 2008 à 14:20
Pour les treeview, j'ai donc ajouté le code suivant.
Avec le treeview de l'explorateur Windows, cela fonctionne parfois, mais pas toujours (!). Idem pour la listview de l'explorateur.

If InStr(1, ";SysTreeView32;TreeView20WndClass;", ";" & sClass & ";", vbTextCompare) Then
GetWindowThreadProcessId vhwnd, nPid
hprocess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE Or PROCESS_QUERY_INFORMATION, False, nPid)
If hprocess <> -1 Then
tv = TreeView_GetRoot(vhwnd) 'noeud racine
'vsresult = get_treeview_item_text(vhwnd, hprocess, tv) & vbNewLine 'récupération du nom
'tv = TreeView_GetChild(vhwnd, tv) 'on se place sur son premier fils
vsresult = vsresult & get_treeview_text(vhwnd, hprocess, tv, 0) 'on demande la récupération de l'arbre à partir de ce permier fils
CloseHandle hprocess
End If

Public Function TreeView_GetRoot(hwnd As Long) As Long
TreeView_GetRoot = TreeView_GetNextItem(hwnd, 0, TVGN_ROOT)
End Function

Public Function TreeView_GetChild(hwnd As Long, hItem As Long) As Long
TreeView_GetChild = TreeView_GetNextItem(hwnd, hItem, TVGN_CHILD)
End Function

Public Function TreeView_GetNextItem(hwnd As Long, _
hItem As Long, _
flag As Long) As Long
TreeView_GetNextItem = SendMessage(hwnd, _
TVM_GETNEXTITEM, _
flag, _
ByVal hItem)
End Function

'pour récursivité
Private Function get_treeview_text(vhwnd As Long, hprocess As Long, ByVal tv As Long, level As Integer) As String
Dim vsresult As String
Dim tmp As String
While tv <> 0
vsresult = vsresult & String(level, vbTab) & get_treeview_item_text(vhwnd, hprocess, tv) & vbNewLine
tmp = get_treeview_text(vhwnd, hprocess, TreeView_GetChild(vhwnd, tv), level + 1)
vsresult = vsresult & tmp
tv = TreeView_GetNextItem(vhwnd, tv, TVGN_NEXT)
Wend
get_treeview_text = vsresult
End Function

Private Function get_treeview_item_text(vhwnd As Long, hprocess As Long, tv As Long) As String
Dim tvi As TVITEM
Dim mem As Long
Dim nLength As Long
Dim sBuffer As String
With tvi
.mask = TVIF_TEXT
.cchTextMax = 512
End With
sBuffer = Space$(512)
tvi.pszText = VirtualAllocEx(hprocess, ByVal 0&, 512, MEM_COMMIT, PAGE_READWRITE)
mem = VirtualAllocEx(hprocess, ByVal 0&, LenB(tvi), MEM_COMMIT, PAGE_READWRITE)
tvi.hItem = tv
WriteProcessMemory hprocess, ByVal mem, tvi, LenB(tvi), nLength
Call SendMessage(vhwnd, TVM_GETITEM, 0&, ByVal mem)
ReadProcessMemory hprocess, ByVal tvi.pszText, ByVal sBuffer, 512, ByVal 0&
On Error Resume Next
get_treeview_item_text = Left$(sBuffer, InStr(sBuffer, vbNullChar) - 1)
On Error GoTo 0
VirtualFreeEx hprocess, mem, 0, MEM_RELEASE
VirtualFreeEx hprocess, tvi.pszText, 0, MEM_RELEASE
End Function
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
22 avril 2008 à 13:29
Merci à toi.
j'ai compris.

Je finis le code pour les treeview et je le mets ici, si tu n'as pas le temps de la faire.
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 avril 2008 à 13:22
dans l'absolu, oui, mais il faudrait tout de même faire
pszText = Space$( 512 )
pour allouer de la mémoire.

le String est interpreté lors de l'appel à l'API. Celle-ci recevra un pointeur mémoire vers les caractères...
mais ce pointeur ne désignerai pas une adresse valide dans l'espace mémoire du processus cible...

c'est pour cela que l'on fait des VirtualAlloc, etc ; pour que le pointeur désigne une adresse mémoire conforme, dans l'espace mémoire du processus en charge de relmplir notre LVITEM
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
22 avril 2008 à 12:30
Pour ma culture perso :
pourquoi ne peut-on pas faire : (psztext as string)
et se passer d'allouer de la mémoire ?

Private Type LVITEM
mask As Long
iItem As Long
iSubItem As Long
state As Long
stateMask As Long
pszText As STRING
cchTextMax As Long
iImage As Long
lParam As Long
iIndent As Long
iGroupId As Long
cColumns As Long
puColumns As Long
End Type
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 avril 2008 à 11:12
non, pas eu le temps, mais ca ne doit pas etre complexe.... se baser sur ce que j'ai fait sur les listview, pour aller jouer dans l'espace mémoire du process cible, lui demander des Nodes, etc...
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
22 avril 2008 à 10:57
Je sens que je vais utiliser ta source dans mon logiciel de multi-presse-papier !

Je vais tenter la gestion des treeview. As-tu essayé ?
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
21 avril 2008 à 14:34
On peut même supprimer ce test :

...
'# On récupère l'entete
hHeader = SendMessage(vhWnd, LVM_GETHEADER, 0, ByVal 0&)
If hHeader Then
'# Le nombre de colonnes
nColUbound = SendMessage(hHeader, HDM_GETITEMCOUNT, 0, ByVal 0&) - 1

...
End If
...
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
21 avril 2008 à 14:28
il s'agit d'une listeview de type : ListView20WndClass
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
21 avril 2008 à 14:26
je te donne le détail, ça sera peut-être plus clair :
j'ai créé dans un autre projet une listview configurée en mode lvwReport.
Il y a trois colonnes et des entêtes de colonnes.
Mais ton programme ne me renvoyait que le contenu de la 1ère colonne.
J'ai donc visualisé la valeur renvoyée dans ton programme par sendMessage(vhWnd, LVM_GETVIEW, 0, ByVal 0&) et c'était 0. En modifiant le test sur cette valeur, j'ai pu obtenir les contenus de mes 3 colonnes et leur entêtes.
En tout cas, ça marche du tonnerre, et c'est également une nouvelle façon de récupérer les infos d'un explorateur windows. (avec plus de détails que dans ma dernière source qui ne récupérait que les noms de fichiers via le clipbpoard)
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
21 avril 2008 à 14:16
Si tu es en mode report, l'export te donnera les colonnes
si tu es dans un autre mode tu vas obtenir un mode list (tous les elements a la ligne)

pour ton "renvoie 0" , je suis pas sur de piger... en effet, Const lvwReport = 3
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
21 avril 2008 à 14:07
Merci bien, c'est du joli boulot. et bien commenté cette fois ;-)

pour les listview, la récupération des colonnes et subitems fonctionnent aussi si SendMessage(vhWnd, LVM_GETVIEW, 0, ByVal 0&) renvoie 0 (mode lviewreport).
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
21 avril 2008 à 13:06
reste le Treeview, mais pas le temps, dans l'immédiat.

amusez vous bien aec cet update
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
21 avril 2008 à 11:29
Je suis en train d'ajouter la gestion de quelques types de fenetre supplémentaires
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
21 avril 2008 à 09:31
Pour tester avec une listbox d'un projet VB6 j'ai dû utiliser ThunderListbox à la place de Listbox. Ca marche nickel.
Par contre je n'arrive pas à modifier le programme pour un textbox.
J'imagine que ça ne doit pas être super compliqué ?
oommeeggaa3d Messages postés 97 Date d'inscription dimanche 24 avril 2005 Statut Membre Dernière intervention 3 septembre 2010
21 avril 2008 à 09:14
Excellent et ça donne des idées !
Mais ça manque un peu de commentaires.
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
20 avril 2008 à 06:06
Récupérer facilement dans une TextBox la liste des elements situés dans une ListBox.
En effet, depuis une TextBox, il est possible de modifier ces éléments, de faire un copier coller...

J'ai fait cette mini source pour le boulot: comme je l'ai expliqué, j'ai une appli au boulot qui affiche ses messages de log dans une zone de liste.
j'avais besoin d'envoyer un rapport par mail, basé sur des infos contenues dans la log.

plutot que de recopier a la maon les infos dont j'avais besoin, j'ai préféré un outil simple a mettre en oeuvre... (un simple drag & drop)
cs_muad-dib Messages postés 103 Date d'inscription lundi 9 avril 2001 Statut Membre Dernière intervention 16 juillet 2008
19 avril 2008 à 23:13
Pardon mais je ne saisis pas bien le but du programme?
Rejoignez-nous