' code trop long, depuis qu'il gère d'autres types de fenetre ' => voir ZIP
Télécharger le zip
Pardon mais je ne saisis pas bien le but du programme?
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)
Excellent et ça donne des idées !Mais ça manque un peu de commentaires.
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é ?
Je suis en train d'ajouter la gestion de quelques types de fenetre supplémentaires
reste le Treeview, mais pas le temps, dans l'immédiat.amusez vous bien aec cet update
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).
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
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)
il s'agit d'une listeview de type : ListView20WndClass
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 ...
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é ?
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...
Pour ma culture perso :pourquoi ne peut-on pas faire : (psztext as string)et se passer d'allouer de la mémoire ?Private Type LVITEMmask As LongiItem As LongiSubItem As Longstate As LongstateMask As LongpszText As STRINGcchTextMax As LongiImage As LonglParam As LongiIndent As LongiGroupId As LongcColumns As LongpuColumns As LongEnd Type
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
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.
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 hprocessEnd IfPublic Function TreeView_GetRoot(hwnd As Long) As LongTreeView_GetRoot = TreeView_GetNextItem(hwnd, 0, TVGN_ROOT)End FunctionPublic Function TreeView_GetChild(hwnd As Long, hItem As Long) As LongTreeView_GetChild = TreeView_GetNextItem(hwnd, hItem, TVGN_CHILD)End FunctionPublic Function TreeView_GetNextItem(hwnd As Long, _hItem As Long, _flag As Long) As LongTreeView_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 StringDim vsresult As StringDim tmp As StringWhile 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)Wendget_treeview_text = vsresultEnd FunctionPrivate Function get_treeview_item_text(vhwnd As Long, hprocess As Long, tv As Long) As StringDim tvi As TVITEMDim mem As LongDim nLength As LongDim sBuffer As StringWith tvi .mask = TVIF_TEXT .cchTextMax = 512End WithsBuffer = 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 = tvWriteProcessMemory hprocess, ByVal mem, tvi, LenB(tvi), nLengthCall SendMessage(vhwnd, TVM_GETITEM, 0&, ByVal mem)ReadProcessMemory hprocess, ByVal tvi.pszText, ByVal sBuffer, 512, ByVal 0&On Error Resume Nextget_treeview_item_text = Left$(sBuffer, InStr(sBuffer, vbNullChar) - 1)On Error GoTo 0VirtualFreeEx hprocess, mem, 0, MEM_RELEASEVirtualFreeEx hprocess, tvi.pszText, 0, MEM_RELEASEEnd Function
Précision : ça ne fonctionnait plus avec mon explorermais 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.
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.
j'ai intégré la gestion des TreeViewsregarde si tu as toujorus le même soucis...
Ouf, le problème peut se régler :Le souci vient de là :http://www.vbfrance.com/infomsg_VIRTUALFREEEX-SUITE_147596.aspx#1
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
Excellent !
Se souvenir du profil
Mot de passe oublié ? / Activation de compteCréer un compte