How do I do a ListView Search?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jon Ripley

    How do I do a ListView Search?

    Using VB6 (for two weeks!)

    I could get a ListBox search working perfectly but with a ListView it has
    completely stumped me. I've not found any previous posts that have helped :(

    The user enters a string into a text box (txtStreet) and as they type any
    matching entry in the listview (lsvStreets) is highlighted and made visible.
    The search highlights the first item starting with the text in txtStreet.

    The listview contains 6,000 rows of 7 columns, only the first column is
    relevent in any search.

    With the ListBox I was using...

    Private Declare Function SendMessage Lib "User32" _
    Alias "SendMessag eA" (ByVal _
    hWnd As Long, _
    ByVal wMsg As Integer, _
    ByVal wParam As String, _
    lParam As Any) As Long

    Const LB_FINDSTRING = &H18F

    And in the txtStreet_Chang e function:

    MsgBox SendMessage(lsv Streets.hWnd, LB_FINDSTRING, txtStreet ByVal
    txtStreet.Text)

    I'm going round the web looking for examples, tutorials, etc but so far
    nothing has helped or worked.

    Thanks.


  • Jon Ripley

    #2
    Re: How do I do a ListView Search?

    Progress...I managed to finally get it working with the following code,
    which leads me to a new problem :)

    I would like the found item to be highlighted and also to be preferably the
    top visible item, I would really appreciate any help anyone can give me with
    this.

    Thanks...
    Jon R.

    === Code ===

    Private Sub cmdSearch_Click ()
    Static lastIndex As Long
    Dim nIndex As Long
    Dim itmx As ListItem

    If txtStreet <> "" Then
    Set itmx = lsvStreets.Find Item(txtStreet, lvwText, 1, lvwPartial)
    If Not itmx Is Nothing Then
    itmx.Selected = True
    itmx.EnsureVisi ble
    lastIndex = itmx.Index
    End If
    End If
    End Sub



    Comment

    • Randy Birch

      #3
      Re: How do I do a ListView Search?

      Private Const LVM_FIRST = &H1000
      Private Const LVM_GETCOUNTPER PAGE As Long = (LVM_FIRST + 40)

      Private Declare Function SendMessage Lib "user32" _
      Alias "SendMessag eA" _
      (ByVal hwnd As Long, _
      ByVal wMsg As Long, _
      ByVal wParam As Long, _
      lParam As Any) As Long



      Private Sub Command1_Click( )

      Static lastIndex As Long
      Dim nIndex As Long
      Dim itmx As ListItem
      Dim topIndex As Long

      Set itmx = ListView1.FindI tem(txtStreet.T ext, lvwText, 1, lvwPartial)

      If Not itmx Is Nothing Then
      topIndex = SetListViewTopI ndex(itmx.Index )
      itmx.Selected = True
      lastIndex = itmx.Index
      End If

      Label1.Caption = topIndex

      End Sub


      Private Function SetListViewTopI ndex(lv As ListView, ByVal itemToTop As
      Long) As Long

      Dim lvItemsPerPage As Long
      Dim lvNeededItems As Long

      'determine if desired index + number
      'of items in view will exceed total
      'items in the control
      lvItemsPerPage = GetListviewVisi bleCount(lv.hwn d)
      lvNeededItems = (itemToTop - lvItemsPerPage)

      If (itemToTop + lvItemsPerPage) > lv.ListItems.Co unt Then

      'yes, so scroll end of listview
      'into view
      lv.ListItems(lv .ListItems.Coun t).EnsureVisibl e
      SetListViewTopI ndex = (lv.ListItems.C ount - lvItemsPerPage) + 1
      Else

      lv.ListItems((i temToTop + lvItemsPerPage) - 1).EnsureVisibl e
      SetListViewTopI ndex = itemToTop

      End If

      End Function


      Private Function GetListviewVisi bleCount() As Long

      GetListviewVisi bleCount = SendMessage(Lis tView1.hwnd, _
      LVM_GETCOUNTPER PAGE, _
      0&, _
      ByVal 0&)

      End Function



      --

      Randy Birch
      MVP Visual Basic

      Please respond only to the newsgroups so all can benefit.

      There's no place like 127.0.0.1


      "Jon Ripley" <news@stryker.f reeserve.co.uk> wrote in message
      news:NRRQb.9280 $3g2.100304993@ news-text.cableinet. net...
      : Progress...I managed to finally get it working with the following code,
      : which leads me to a new problem :)
      :
      : I would like the found item to be highlighted and also to be preferably
      the
      : top visible item, I would really appreciate any help anyone can give me
      with
      : this.
      :
      : Thanks...
      : Jon R.
      :
      : === Code ===
      :
      : Private Sub cmdSearch_Click ()
      : Static lastIndex As Long
      : Dim nIndex As Long
      : Dim itmx As ListItem
      :
      : If txtStreet <> "" Then
      : Set itmx = lsvStreets.Find Item(txtStreet, lvwText, 1, lvwPartial)
      : If Not itmx Is Nothing Then
      : itmx.Selected = True
      : itmx.EnsureVisi ble
      : lastIndex = itmx.Index
      : End If
      : End If
      : End Sub
      :
      :
      :


      Comment

      • Randy Birch

        #4
        Re: How do I do a ListView Search?

        ....whoops ... the call to the topindex routine should have read:

        topIndex = SetListViewTopI ndex(ListView1, itmx.Index)

        --

        Randy Birch
        MVP Visual Basic

        Please respond only to the newsgroups so all can benefit.

        There's no place like 127.0.0.1


        "Randy Birch" <rgb_removethis @mvps.org> wrote in message
        news:d3UQb.8573 $Vk2.6139@news0 1.bloor.is.net. cable.rogers.co m...
        : Private Const LVM_FIRST = &H1000
        : Private Const LVM_GETCOUNTPER PAGE As Long = (LVM_FIRST + 40)
        :
        : Private Declare Function SendMessage Lib "user32" _
        : Alias "SendMessag eA" _
        : (ByVal hwnd As Long, _
        : ByVal wMsg As Long, _
        : ByVal wParam As Long, _
        : lParam As Any) As Long
        :
        :
        :
        : Private Sub Command1_Click( )
        :
        : Static lastIndex As Long
        : Dim nIndex As Long
        : Dim itmx As ListItem
        : Dim topIndex As Long
        :
        : Set itmx = ListView1.FindI tem(txtStreet.T ext, lvwText, 1, lvwPartial)
        :
        : If Not itmx Is Nothing Then
        : topIndex = SetListViewTopI ndex(itmx.Index )
        : itmx.Selected = True
        : lastIndex = itmx.Index
        : End If
        :
        : Label1.Caption = topIndex
        :
        : End Sub
        :
        :
        : Private Function SetListViewTopI ndex(lv As ListView, ByVal itemToTop As
        : Long) As Long
        :
        : Dim lvItemsPerPage As Long
        : Dim lvNeededItems As Long
        :
        : 'determine if desired index + number
        : 'of items in view will exceed total
        : 'items in the control
        : lvItemsPerPage = GetListviewVisi bleCount(lv.hwn d)
        : lvNeededItems = (itemToTop - lvItemsPerPage)
        :
        : If (itemToTop + lvItemsPerPage) > lv.ListItems.Co unt Then
        :
        : 'yes, so scroll end of listview
        : 'into view
        : lv.ListItems(lv .ListItems.Coun t).EnsureVisibl e
        : SetListViewTopI ndex = (lv.ListItems.C ount - lvItemsPerPage) + 1
        : Else
        :
        : lv.ListItems((i temToTop + lvItemsPerPage) - 1).EnsureVisibl e
        : SetListViewTopI ndex = itemToTop
        :
        : End If
        :
        : End Function
        :
        :
        : Private Function GetListviewVisi bleCount() As Long
        :
        : GetListviewVisi bleCount = SendMessage(Lis tView1.hwnd, _
        : LVM_GETCOUNTPER PAGE, _
        : 0&, _
        : ByVal 0&)
        :
        : End Function
        :
        :
        :
        : --
        :
        : Randy Birch
        : MVP Visual Basic
        : http://vbnet.mvps.org/
        : Please respond only to the newsgroups so all can benefit.
        :
        : There's no place like 127.0.0.1
        :
        :
        : "Jon Ripley" <news@stryker.f reeserve.co.uk> wrote in message
        : news:NRRQb.9280 $3g2.100304993@ news-text.cableinet. net...
        : : Progress...I managed to finally get it working with the following code,
        : : which leads me to a new problem :)
        : :
        : : I would like the found item to be highlighted and also to be preferably
        : the
        : : top visible item, I would really appreciate any help anyone can give me
        : with
        : : this.
        : :
        : : Thanks...
        : : Jon R.
        : :
        : : === Code ===
        : :
        : : Private Sub cmdSearch_Click ()
        : : Static lastIndex As Long
        : : Dim nIndex As Long
        : : Dim itmx As ListItem
        : :
        : : If txtStreet <> "" Then
        : : Set itmx = lsvStreets.Find Item(txtStreet, lvwText, 1, lvwPartial)
        : : If Not itmx Is Nothing Then
        : : itmx.Selected = True
        : : itmx.EnsureVisi ble
        : : lastIndex = itmx.Index
        : : End If
        : : End If
        : : End Sub
        : :
        : :
        : :
        :
        :


        Comment

        • Randy Birch

          #5
          Re: How do I do a ListView Search?

          Damn ... hang on, that only works if the index to set is further down the
          list....

          --

          Randy Birch
          MVP Visual Basic

          Please respond only to the newsgroups so all can benefit.

          There's no place like 127.0.0.1


          "Randy Birch" <rgb_removethis @mvps.org> wrote in message
          news:%3UQb.8590 $Vk2.7290@news0 1.bloor.is.net. cable.rogers.co m...
          : ...whoops ... the call to the topindex routine should have read:
          :
          : topIndex = SetListViewTopI ndex(ListView1, itmx.Index)
          :
          : --
          :
          : Randy Birch
          : MVP Visual Basic
          : http://vbnet.mvps.org/
          : Please respond only to the newsgroups so all can benefit.
          :
          : There's no place like 127.0.0.1
          :
          :
          : "Randy Birch" <rgb_removethis @mvps.org> wrote in message
          : news:d3UQb.8573 $Vk2.6139@news0 1.bloor.is.net. cable.rogers.co m...
          : : Private Const LVM_FIRST = &H1000
          : : Private Const LVM_GETCOUNTPER PAGE As Long = (LVM_FIRST + 40)
          : :
          : : Private Declare Function SendMessage Lib "user32" _
          : : Alias "SendMessag eA" _
          : : (ByVal hwnd As Long, _
          : : ByVal wMsg As Long, _
          : : ByVal wParam As Long, _
          : : lParam As Any) As Long
          : :
          : :
          : :
          : : Private Sub Command1_Click( )
          : :
          : : Static lastIndex As Long
          : : Dim nIndex As Long
          : : Dim itmx As ListItem
          : : Dim topIndex As Long
          : :
          : : Set itmx = ListView1.FindI tem(txtStreet.T ext, lvwText, 1, lvwPartial)
          : :
          : : If Not itmx Is Nothing Then
          : : topIndex = SetListViewTopI ndex(itmx.Index )
          : : itmx.Selected = True
          : : lastIndex = itmx.Index
          : : End If
          : :
          : : Label1.Caption = topIndex
          : :
          : : End Sub
          : :
          : :
          : : Private Function SetListViewTopI ndex(lv As ListView, ByVal itemToTop As
          : : Long) As Long
          : :
          : : Dim lvItemsPerPage As Long
          : : Dim lvNeededItems As Long
          : :
          : : 'determine if desired index + number
          : : 'of items in view will exceed total
          : : 'items in the control
          : : lvItemsPerPage = GetListviewVisi bleCount(lv.hwn d)
          : : lvNeededItems = (itemToTop - lvItemsPerPage)
          : :
          : : If (itemToTop + lvItemsPerPage) > lv.ListItems.Co unt Then
          : :
          : : 'yes, so scroll end of listview
          : : 'into view
          : : lv.ListItems(lv .ListItems.Coun t).EnsureVisibl e
          : : SetListViewTopI ndex = (lv.ListItems.C ount - lvItemsPerPage) + 1
          : : Else
          : :
          : : lv.ListItems((i temToTop + lvItemsPerPage) - 1).EnsureVisibl e
          : : SetListViewTopI ndex = itemToTop
          : :
          : : End If
          : :
          : : End Function
          : :
          : :
          : : Private Function GetListviewVisi bleCount() As Long
          : :
          : : GetListviewVisi bleCount = SendMessage(Lis tView1.hwnd, _
          : : LVM_GETCOUNTPER PAGE, _
          : : 0&, _
          : : ByVal 0&)
          : :
          : : End Function
          : :
          : :
          : :
          : : --
          : :
          : : Randy Birch
          : : MVP Visual Basic
          : : http://vbnet.mvps.org/
          : : Please respond only to the newsgroups so all can benefit.
          : :
          : : There's no place like 127.0.0.1
          : :
          : :
          : : "Jon Ripley" <news@stryker.f reeserve.co.uk> wrote in message
          : : news:NRRQb.9280 $3g2.100304993@ news-text.cableinet. net...
          : : : Progress...I managed to finally get it working with the following
          code,
          : : : which leads me to a new problem :)
          : : :
          : : : I would like the found item to be highlighted and also to be
          preferably
          : : the
          : : : top visible item, I would really appreciate any help anyone can give
          me
          : : with
          : : : this.
          : : :
          : : : Thanks...
          : : : Jon R.
          : : :
          : : : === Code ===
          : : :
          : : : Private Sub cmdSearch_Click ()
          : : : Static lastIndex As Long
          : : : Dim nIndex As Long
          : : : Dim itmx As ListItem
          : : :
          : : : If txtStreet <> "" Then
          : : : Set itmx = lsvStreets.Find Item(txtStreet, lvwText, 1, lvwPartial)
          : : : If Not itmx Is Nothing Then
          : : : itmx.Selected = True
          : : : itmx.EnsureVisi ble
          : : : lastIndex = itmx.Index
          : : : End If
          : : : End If
          : : : End Sub
          : : :
          : : :
          : : :
          : :
          : :
          :
          :


          Comment

          • Jon Ripley

            #6
            Re: How do I do a ListView Search?

            Many thanks, got it working now :)

            Jon R.


            Comment

            • Randy Birch

              #7
              Re: How do I do a ListView Search?

              Here's the revised code ... the demo uses a listview, label and three
              command buttons....

              Option Explicit

              Private Const LVM_FIRST = &H1000
              Private Const LVM_GETTOPINDEX = (LVM_FIRST + 39)
              Private Const LVM_GETCOUNTPER PAGE As Long = (LVM_FIRST + 40)

              Private Declare Function SendMessage Lib "user32" _
              Alias "SendMessag eA" _
              (ByVal hwnd As Long, _
              ByVal wMsg As Long, _
              ByVal wParam As Long, _
              lParam As Any) As Long


              Private Function ListView_SetTop Index(lv As ListView, ByVal itemToTop As
              Long) As Long

              Dim lvItemsPerPage As Long
              Dim lvNeededItems As Long
              Dim lvCurrentTopInd ex As Long

              'determine if desired index + number
              'of items in view will exceed total
              'items in the control
              lvCurrentTopInd ex = ListView_GetTop Index(lv.hwnd) + 1 '0-based!
              lvItemsPerPage = ListView_GetVis ibleCount(lv.hw nd)
              lvNeededItems = (itemToTop - lvItemsPerPage)

              'is current index above or below
              'desired index?
              If lvCurrentTopInd ex > itemToTop Then

              'it is above the desired index, so
              'scroll up. The item will automatically
              'be positioned at the top
              lv.ListItems((i temToTop)).Ensu reVisible

              Else

              'it's below, so based on whether there
              'are sufficient items to set to the topindex ...
              If (itemToTop + lvItemsPerPage) > lv.ListItems.Co unt Then

              'it is below but it can't be set to
              'the top as the control has insufficient
              'items, so just scroll to the end of listview
              lv.ListItems(lv .ListItems.Coun t).EnsureVisibl e

              Else

              'it is below, and since a listview
              'always moves the item just into view,
              'have it instead move to the top by
              'faking item we want to 'EnsureVisible'
              'the item lvItemsPerPage -1 below the actual
              'index of interest.
              lv.ListItems((i temToTop + lvItemsPerPage) - 1).EnsureVisibl e

              End If

              End If

              'return a 1-based top index
              'as sign of success.
              ListView_SetTop Index = ListView_GetTop Index(lv.hwnd) + 1

              End Function


              Private Function ListView_GetTop Index(hwndlv As Long) As Long

              ListView_GetTop Index = SendMessage(hwn dlv, _
              LVM_GETTOPINDEX , _
              0&, _
              ByVal 0&)

              End Function
              Private Function ListView_GetVis ibleCount(ByVal hwndlv As Long) As Long

              ListView_GetVis ibleCount = SendMessage(hwn dlv, _
              LVM_GETCOUNTPER PAGE, _
              0&, _
              ByVal 0&)

              End Function
              Private Sub Command1_Click( )

              Static lastIndex As Long
              Dim nIndex As Long
              Dim itmx As ListItem
              Dim topIndex As Long

              Set itmx = ListView1.FindI tem("main item100", lvwText, 1, lvwPartial)

              If Not itmx Is Nothing Then
              topIndex = ListView_SetTop Index(ListView1 , itmx.Index)
              itmx.Selected = True
              lastIndex = itmx.Index
              End If

              Label1.Caption = topIndex

              End Sub

              Private Sub Command2_Click( )

              Static lastIndex As Long
              Dim nIndex As Long
              Dim itmx As ListItem
              Dim topIndex As Long

              Set itmx = ListView1.FindI tem("main item197", lvwText, 1, lvwPartial)

              If Not itmx Is Nothing Then
              topIndex = ListView_SetTop Index(ListView1 , itmx.Index)
              itmx.Selected = True
              lastIndex = itmx.Index
              End If

              Label1.Caption = topIndex

              End Sub

              Private Sub Command3_Click( )

              Static lastIndex As Long
              Dim nIndex As Long
              Dim itmx As ListItem
              Dim topIndex As Long

              Set itmx = ListView1.FindI tem("main item2", lvwText, 1, lvwPartial)

              If Not itmx Is Nothing Then
              topIndex = ListView_SetTop Index(ListView1 , itmx.Index)
              itmx.Selected = True
              lastIndex = itmx.Index
              End If

              Label1.Caption = topIndex


              End Sub


              Private Sub Form_Load()

              Dim itmx As ListItem
              Dim cnt As Long

              With ListView1
              .ColumnHeaders. Add , , "main"
              .ColumnHeaders. Add , , "sub 1"
              .ColumnHeaders. Add , , "sub 2"
              .ColumnHeaders. Add , , "sub 3"

              For cnt = 1 To 200
              Set itmx = .ListItems.Add( , , "main item" & CStr(cnt))
              itmx.SubItems(1 ) = "subitem 1," & CStr(cnt)
              itmx.SubItems(2 ) = "subitem 3," & CStr(cnt)
              itmx.SubItems(3 ) = "subitem 4," & CStr(cnt)
              Next

              .SortKey = 0
              .Sorted = False
              .View = lvwReport
              .FullRowSelect = True
              .LabelEdit = lvwManual

              End With

              Command1.Captio n = "mid-way"
              Command2.Captio n = "item 197"
              Command3.Captio n = "item 2"

              End Sub

              Private Sub ListView1_Colum nClick(ByVal ColumnHeader As ColumnHeader)

              'sort the items
              ListView1.SortK ey = ColumnHeader.In dex - 1
              ListView1.SortO rder = Abs(Not ListView1.SortO rder = 1)
              ListView1.Sorte d = True

              End Sub


              --

              Randy Birch
              MVP Visual Basic

              Please respond only to the newsgroups so all can benefit.

              There's no place like 127.0.0.1


              "Jon Ripley" <news@stryker.f reeserve.co.uk> wrote in message
              news:srUQb.9394 $ov3.101608493@ news-text.cableinet. net...
              : Many thanks, got it working now :)
              :
              : Jon R.
              :
              :


              Comment

              • method
                New Member
                • Feb 2006
                • 6

                #8
                Randy Birch Thank u for u nice code. could tell me how i can search external listview usiing your code?Thanks
                Last edited by method; Jun 17 '06, 09:38 AM.

                Comment

                • method
                  New Member
                  • Feb 2006
                  • 6

                  #9
                  want to subscribe

                  Comment

                  Working...