EXTRAIRE LE TEXTE DES FENETRES D'APPLICATIONS TIERCES (LISTBOX, LISTVIEW, TEXTBO
cs_muad-dib
Messages postés103Date d'inscriptionlundi 9 avril 2001StatutMembreDernière intervention16 juillet 2008
-
19 avril 2008 à 23:13
Chouchensb
Messages postés64Date d'inscriptionjeudi 3 mars 2005StatutMembreDerniè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.
Chouchensb
Messages postés64Date d'inscriptionjeudi 3 mars 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és64Date d'inscriptionjeudi 3 mars 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 3 août 2010 à 01:06
dans quel soft puis-je trouver une telle status bar ?
Chouchensb
Messages postés64Date d'inscriptionjeudi 3 mars 2005StatutMembreDerniè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és25Date d'inscriptionmercredi 26 novembre 2003StatutMembreDernière intervention13 juin 2009 10 janv. 2009 à 00:13
Super
beebopcmoi
Messages postés6Date d'inscriptionvendredi 3 novembre 2006StatutMembreDernière intervention23 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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 4 oct. 2008 à 18:21
la couleur me semble complexe a obtenir. la reste ca devrait aller
beebopcmoi
Messages postés6Date d'inscriptionvendredi 3 novembre 2006StatutMembreDernière intervention23 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 :
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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 30 sept. 2008 à 05:15
voir la valeur de state, dans les TVITEM.
TVIS_BOLD => controle le gras.
beebopcmoi
Messages postés6Date d'inscriptionvendredi 3 novembre 2006StatutMembreDernière intervention23 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és13272Date d'inscriptionlundi 13 décembre 2004StatutMembreDernière intervention 3 février 201847 23 mai 2008 à 16:25
dommage, la ListBox cochable de WindowsUpdate n'est pas supportée :(
cs_AGG
Messages postés46Date d'inscriptionjeudi 15 avril 2004StatutMembreDernière intervention 9 décembre 2012 4 mai 2008 à 12:56
Excellent !
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDernière intervention 3 septembre 2010 22 avril 2008 à 15:31
Ouf, le problème peut se régler :
Le souci vient de là :
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDernière intervention 3 septembre 2010 21 avril 2008 à 14:28
il s'agit d'une listeview de type : ListView20WndClass
oommeeggaa3d
Messages postés97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 21 avril 2008 à 11:29
Je suis en train d'ajouter la gestion de quelques types de fenetre supplémentaires
oommeeggaa3d
Messages postés97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és97Date d'inscriptiondimanche 24 avril 2005StatutMembreDerniè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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és103Date d'inscriptionlundi 9 avril 2001StatutMembreDernière intervention16 juillet 2008 19 avril 2008 à 23:13
Pardon mais je ne saisis pas bien le but du programme?
4 août 2010 à 10:27
Bien vu pour les lettres p, j'avais pas vu. Merci beaucoup pour le coup de main néanmoins !
Simon
4 août 2010 à 09:38
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...
4 août 2010 à 09:27
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
3 août 2010 à 11:55
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).
3 août 2010 à 01:06
2 août 2010 à 23:11
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 ?
10 janv. 2009 à 00:13
5 oct. 2008 à 13:23
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....
4 oct. 2008 à 18:21
2 oct. 2008 à 16:47
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?
30 sept. 2008 à 05:15
TVIS_BOLD => controle le gras.
voir ici. http://msdn.microsoft.com/en-us/library/ms913992.aspx
29 sept. 2008 à 18:13
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?
23 mai 2008 à 16:25
4 mai 2008 à 12:56
22 avril 2008 à 16:11
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
22 avril 2008 à 15:31
Le souci vient de là :
http://www.vbfrance.com/infomsg_VIRTUALFREEEX-SUITE_147596.aspx#1
22 avril 2008 à 15:27
regarde si tu as toujorus le même soucis...
22 avril 2008 à 15:13
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.
22 avril 2008 à 14:43
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.
22 avril 2008 à 14:20
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
22 avril 2008 à 13:29
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.
22 avril 2008 à 13:22
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
22 avril 2008 à 12:30
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
22 avril 2008 à 11:12
22 avril 2008 à 10:57
Je vais tenter la gestion des treeview. As-tu essayé ?
21 avril 2008 à 14:34
...
'# 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
...
21 avril 2008 à 14:28
21 avril 2008 à 14:26
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)
21 avril 2008 à 14:16
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
21 avril 2008 à 14:07
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).
21 avril 2008 à 13:06
amusez vous bien aec cet update
21 avril 2008 à 11:29
21 avril 2008 à 09:31
Par contre je n'arrive pas à modifier le programme pour un textbox.
J'imagine que ça ne doit pas être super compliqué ?
21 avril 2008 à 09:14
Mais ça manque un peu de commentaires.
20 avril 2008 à 06:06
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)
19 avril 2008 à 23:13