This topic is now archived and is closed to further replies.


LB_GETCOUNT (on a tree control?)

Recommended Posts

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?

Share this post

Link to post
Share on other sites
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 = 1
End 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
GetMemSharedNT = VirtualAllocEx(ByVal hProcess, ByVal 0&, ByVal memSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
End Function

Public Sub FreeMemSharedNT(ByVal hProcess As Long, ByVal MemAddress As Long, ByVal memSize As Long)
Call VirtualFreeEx(hProcess, ByVal MemAddress, memSize, MEM_RELEASE)
CloseHandle hProcess
End Sub

[edited by - simbiant on August 12, 2003 11:32:54 PM]

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post

Link to post
Share on other sites
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 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_ITEM
I = findKTree
MsgBox X //<--- this works

theItem.hItem = X
theItem.mask = TVIF_TEXT
//theItem.pszText = ?

theItem.cchTextMax = 64
X = SendMessage(I, TVM_GETITEMA, 0, theItem)
MsgBox X
Msgbox 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.

Share this post

Link to post
Share on other sites
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?

Share this post

Link to post
Share on other sites