LB_GETCOUNT (on a tree control?)

Started by
8 comments, last by simbiant 20 years, 8 months ago
I''m trying to retrieve the number of items in a treeview, as well as the actual items themselves through straightforward Win32 API. On most listboxes, I''ve always been able to use methods such as this.. i = SendMessage(nWindow, LB_GETCOUNT, 0, 0) And it would work fine, but the particular control class I''m trying to work with is a "systreeview32". Kazaa, for instance, uses this type of control for it''s search results. However, the above code does not work on this type of control, which I''m guessing is because, well, it''s a tree and not a list. Does anyone know of any window messages I could send to a systreeview32 to get information like it''s count and what not?
Advertisement
any ideas?
Look into the TVN_xxx notification, TVM_xxx message and TVS_xxx style identifiers.
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
TVM_GETCOUNT
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
alright, much thanks. but now I've encountered the problem of copying/retrieving the contents of a treeview.

i'm aware that it's not possible to retrieve this information simply by sending a TVM_GETITEMW message and hoping for the response.. anyway, I found an example for retrieving the contents of a ListView control, and tried modifying it to work with the TreeView control using the TV set of messages. the place which I downloaded the example from said that it would work anyone tried switching it to TreeView, but obviously it's not.. here's my block of code, and yes, all of the TVM_ and TV_ messages/types are declared properly:

Public Function getTreeItems() As Long   Dim pid As Long, tid As Long   Dim hProcess As Long, nCount As Long, lWritten As Long, I As Long   Dim lpSysShared As Long, hFileMapping As Long, dwSize As Long   Dim lpSysShared2 As Long, hFileMapping2 As Long   Dim li As TV_ITEM   Dim lt As TV_TEXT, hLV As Long   hLV = findKTree   tid = GetWindowThreadProcessId(hLV, pid)   nCount = SendMessage(hLV, TVM_GETCOUNT, 0, 0&)   If nCount = 0 Then Exit Function   li.cchTextMax = 80   dwSize = Len(li)      lpSysShared = GetMemSharedNT(pid, dwSize, hProcess)      lpSysShared2 = GetMemSharedNT(pid, LenB(lt), hProcess)      For I = 0 To nCount - 1          li.pszText = lpSysShared2          li.cchTextMax = 80          li.hItem = I          li.mask = TVIF_TEXT          WriteProcessMemory hProcess, ByVal lpSysShared, li, dwSize, lWritten          WriteProcessMemory hProcess, ByVal lpSysShared2, lt, LenB(lt), lWritten          SendMessage hLV, TVM_GETITEMW, 0, ByVal lpSysShared          Call ReadProcessMemory(hProcess, ByVal lpSysShared2, lt, LenB(lt), lWritten)                    frmMain.lstContents.AddItem StrConv(lt.sItemText, vbFromUnicode)      Next I      FreeMemSharedNT hProcess, lpSysShared, dwSize      FreeMemSharedNT hProcess, lpSysShared2, LenB(lt)   getTreeItems = 1End Function


and yes, getKTree returns the valid hWnd for the TreeView.

the listbox I've created is actually filling up with 230 blank entries (there's 230 items in the TreeView).. so something is working, but obviously the entire thing isn't. it simply won't copy the items.

and also, here's GetMemSharedNT and FreeMemSharedNT in case you're curious (yes, they both work)

Public Function GetMemSharedNT(ByVal pid As Long, ByVal memSize As Long, hProcess As Long) As Long    hProcess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, pid)    GetMemSharedNT = VirtualAllocEx(ByVal hProcess, ByVal 0&, ByVal memSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)End FunctionPublic Sub FreeMemSharedNT(ByVal hProcess As Long, ByVal MemAddress As Long, ByVal memSize As Long)   Call VirtualFreeEx(hProcess, ByVal MemAddress, memSize, MEM_RELEASE)   CloseHandle hProcessEnd Sub


[edited by - simbiant on August 12, 2003 11:32:54 PM]
you''re making the incorrect assumption in this line, "li.hItem = I", that the item handle is an index. it is not. it is a handle. a HTREEITEM to be specific.

the best way to go about this is to retrieve the HTREEITEM of the root item via a TVM_GETNEXTITEM using TVGN_ROOT as wParam and NULL as lParam. with that handle a TVM_GETITEM msg may be used, assuming the handle returned is valid (non-null).

subsequent TVM_GETNEXTITEM msgs using TVGN_NEXT as the wParam and the previously returned HTREEITEM as the lParam would retrieve the next item''s handle in the list.
alright, I understand what you mean. I''ve fixed it up, but it still refuses to work. however, it does get the handle of the root item correctly..so what am I doing wrong now?

by the way I''m only using C++ style rems for posting so you can see it better.

Dim I as long, X as long, theItem as TV_ITEMI = findKTreeX = SendMessage(I, TVM_GETNEXTITEM, TVGN_ROOT, 0)MsgBox X //<--- this workstheItem.hItem = XtheItem.mask = TVIF_TEXT//theItem.pszText = ?theItem.cchTextMax = 64X = SendMessage(I, TVM_GETITEMA, 0, theItem)MsgBox XMsgbox theItem.pszText


I think it has something to do with having to set .pszText to a value beforehand, but I don''t know what. someone told me to set it to "Space(64)", which is just a string of 64 blank spaces.. but I can''t because .pszText is defined as a LONG, and must be a LONG.

if I don''t set it to anything, the final SendMessage returns a 0..if I set it to a number like 64, it still fails.
ugh: I just discovered that the TV_ITEM type is a far pointer in C++.. so I don''t know how to get VB to compensate for that, because TVM_GETITEMA will not work.

so..any ideas?
...
...

Kult House - Fresh Production Media

This topic is closed to new replies.

Advertisement