Atlanta Custom Software Development 

 
   Search        Code/Page
 

User Login
Email

Password

 

Forgot the Password?
Services
» Web Development
» Maintenance
» Data Integration/BI
» Information Management
Programming
  Database
Automation
OS/Networking
Graphics
Links
Tools
» Regular Expr Tester
» Free Tools


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                   'Long pointer
  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)

' Return the binding rectangle for the TreeView item whose
' handle is passed in the second argument. If the 3rd argument
' is True it returns the bounding rectangle for the text portion
' of the node, otherwise it returns the bounding rectangle for
' the entire row.
'
' The result rectangle isn't clipped to the TreeView's visibile portion
' Coordinates are relative to the TreeView's client area
'
' You can use this routine to determine the node under the mouse
' cursor, or to precisely move a textbox or a combobox over a given node.

Private Function GetTreeViewNodeRect(ByVal tv As TreeView, ByVal hItem As Long, _
  Optional IncludeTextOnly As Boolean) As RECT
  Dim lpRect As RECT
  ' the function expects in input the handle of the item
  ' at the beginning of the RECT structure
  lpRect.Left = hItem
  If SendMessage(tv.hwnd, TVM_GETITEMRECT, IncludeTextOnly, lpRect) Then
    ' a non-zero value means that the item is visible
    GetTreeViewNodeRect = lpRect
  End If
End Function

'//Returns a collection of visible item
'//Collection item=Node text
'//Collection Key=Node handle
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                           'repeat this loop as long as we find visible items
    If hItem <> 0 Then
      item.mask = TVIF_TEXT
      item.hItem = hItem
      item.pszText = String$(256, 0)
      item.cchTextMax = 256

      'The next send message will return a value but no callback From the TV_ITEM.pszText
      lret = SendMessage(tv.hwnd, TVM_GETITEM, 0&, item)  'retrive an item by its handle
      's = s & "[" & hItem & "]" & Replace(item.pszText, Chr(0), "") & vbCrLf
      nodetext = Replace(item.pszText, Chr(0), "")
      GetVisibleNodes.Add nodetext, CStr(hItem)
      c = c + 1

      'get next visible item
      hItem = SendMessageLong(tv.hwnd, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, hItem)
    End If

    '//Get next item bound
    If hItem <> 0 Then R = GetTreeViewNodeRect(tv, hItem)

    '//Exit if no next item or item is outside treeview window
    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



Submitted By : Nayan Patel  (Member Since : 5/26/2004 12:23:06 PM)

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.
View all (893) submissions by this author  (Birth Date : 7/14/1981 )


Home   |  Comment   |  Contact Us   |  Privacy Policy   |  Terms & Conditions   |  BlogsZappySys

© 2008 BinaryWorld LLC. All rights reserved.