If you want to retrive only visible item count for treeview control then you can use TreeView1.GetVisibleCount but the problem is this will only return items which are 100% visible so it wont give you exact number.
In this article I will show you the trick to get only visible items of treeview using SendMessage API.
Step-By-Step Example
- Create a standard exe project - Add one command button, one textbox (MultiLine=True, Scrollbar=verticle) - Now press Ctl+C or goto Project->Component and select Microsoft Windows Commom controls 6.0 - Add one treeview control on the form1 - Add the following code in form1 |
Click here to copy the following block | Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _ ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As Long
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" ( _ ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long
Private Const TVIF_TEXT = &H1 Private Const TV_FIRST As Long = &H1100 Private Const TVM_GETITEM As Long = (TV_FIRST + 12) Private Const TVM_GETNEXTITEM As Long = (TV_FIRST + 10) Private Const TVGN_FIRSTVISIBLE = &H5 Private Const TVGN_NEXTVISIBLE = &H6 Private Const TVGN_LASTVISIBLE = &HA Private Const TVGN_PREVIOUSVISIBLE = &H7 Private Const WM_SETREDRAW As Long = &HB Private Const TVM_DELETEITEM As Long = (TV_FIRST + 1) Private Const TVGN_ROOT As Long = &H0
Private Type TV_ITEM mask As Long hItem As Long state As Long stateMask As Long pszText As String cchTextMax As Long iImage As Long iSelectedImage As Long cChildren As Long lParam As Long End Type
Private Type RECT Left As Long Top As Long Right As Long bottom As Long End Type
Private Const TVM_GETITEMRECT = (TV_FIRST + 4)
Private Function GetTreeViewNodeRect(ByVal tv As TreeView, ByVal hItem As Long, _ Optional IncludeTextOnly As Boolean) As RECT Dim lpRect As RECT lpRect.Left = hItem If SendMessage(tv.hwnd, TVM_GETITEMRECT, IncludeTextOnly, lpRect) Then GetTreeViewNodeRect = lpRect End If End Function
Private Function GetVisibleNodes(tv As TreeView) As Collection Dim item As TV_ITEM Dim hItem As Long Dim hItemLast As Long Dim s, c, nodetext As String Dim lret As Long Dim R As RECT, bottom As Integer
Set GetVisibleNodes = New Collection
bottom = tv.Height / Screen.TwipsPerPixelY
hItem = SendMessage(tv.hwnd, TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0) hItemLast = SendMessage(tv.hwnd, TVM_GETNEXTITEM, TVGN_LASTVISIBLE, 0)
Do If hItem <> 0 Then item.mask = TVIF_TEXT item.hItem = hItem item.pszText = String$(256, 0) item.cchTextMax = 256
lret = SendMessage(tv.hwnd, TVM_GETITEM, 0&, item) nodetext = Replace(item.pszText, Chr(0), "") GetVisibleNodes.Add nodetext, CStr(hItem) c = c + 1
hItem = SendMessageLong(tv.hwnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, hItem) End If
If hItem <> 0 Then R = GetTreeViewNodeRect(tv, hItem)
If (hItem = 0) Or (R.bottom > bottom) Then Exit Do Loop
End Function
Private Sub Form_Load() Dim i Command1.Caption = "<< Get Visible Items" Text1 = ""
TreeView1.Nodes.Add , , "Root", "Hello" & Rnd TreeView1.Nodes.Add "Root", tvwChild, "Hello1", "Hello1" TreeView1.Nodes.Add "Root", tvwChild, "Hello2", "Hello2" TreeView1.Nodes.Add "Root", tvwChild, "Hello3", "Hello3" TreeView1.Nodes.Add "Hello3", tvwChild, "Hello3-1", "Hello3-1" TreeView1.Nodes.Add "Hello3", tvwChild, "Hello3-2", "Hello3-2" TreeView1.Nodes.Add "Hello3", tvwChild, "Hello3-3", "Hello3-3" TreeView1.Nodes.Add "Hello3", tvwChild, "Hello3-4", "Hello3-4" TreeView1.Nodes.Add "Root", tvwChild, "Hello4", "Hello4" TreeView1.Nodes.Add "Root", tvwChild, "Hello5", "Hello5" TreeView1.Nodes.Add "Root", tvwChild, "Hello6", "Hello6" TreeView1.Nodes.Add "Root", tvwChild, "Hello7", "Hello7" TreeView1.Nodes.Add "Root", tvwChild, "Hello8", "Hello8" TreeView1.Nodes.Add "Root", tvwChild, "Hello9", "Hello9" TreeView1.Nodes.Add "Root", tvwChild, "Hello10", "Hello10" For i = 1 To 10 TreeView1.Nodes.Add "Root", tvwChild, , "Hello" & Rnd Next TreeView1.Nodes(1).Expanded = True End Sub
Private Sub Command1_Click() Dim colVisibleNodes As New Collection, i Set colVisibleNodes = GetVisibleNodes(TreeView1) Debug.Print String(50, "=") Text1 = "" For i = 1 To colVisibleNodes.Count Debug.Print colVisibleNodes(i) Text1 = Text1 & colVisibleNodes(i) & vbCrLf Next MsgBox "Total Visible items=" & colVisibleNodes.Count End Sub |
|