Visual Basic Common Control API Routines
SendMessage: Using ListView API Check Boxes
     
Posted:   Wednesday January 22, 1998
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB5, Windows 95
OS restrictions:   None
Author:   VBnet - Randy Birch
     
 Prerequisites
This method is intended for Visual Basic 5 or Visual Basic 6 where the Common Control library used is the Mscomctl 5 version (comctl32.ocx). Because the VB6-specific mscomctl.ocx (Common Controls 6) is a complete implementation of comctl32.dll and not reliant on the version of comctl32.dll installed, this routine may not work when applied to a ListView created from the VB6-specific mscomctl.ocx.

Enhanced Comctl32 functionality is only available to users with comctl32.dll version 4.70 or greater installed. This dll is typically installed with IE3.x or greater.


By popular demand, here are several methods you can employ to perform a variety of ListView check box-related operations.

Setcheck: turns on the checkbox for the item passed as the value in the textbox.

GetChecked: displays a MsgBox with a list of currently-selected checked items and their ListIndex.

CheckAll: selects (checks) all the items in the ListView

Uncheck All:   just what it says.

Invert Checks: causes checked items to uncheck, and unchecked items to become checked.

Open XXX: Launches the selected item via ShellExecute, which opens the item in the application associated with the registered extension  The caption changes to reflect the item type, in the example, 'Application'.  The item type is determined by calling SHGetFileInfo in the wrapper function GetFileDescription.

Open All Checked: Uses ShellExecute to launch all selected items.  Note that this can consume a ton of resources if many items are checked.  In addition, because a null is passed as the parameter, applications expecting a command line may display a dialog. Use this button carefully.

This example does not contain all code required to construct the illustration shown. The routines provided here are designed to be applied to an existing project utilizing a ListView control in report view.

 

 BAS Module Code
None.

 Form Code
Add a series of command buttons to a pre-existing ListView project, naming the buttons as indicated in the routines below. Add the following code to the project form:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim fPath As String

Private  Const LVM_FIRST As Long = &H1000
Private  Const LVM_SETITEMSTATE As Long = (LVM_FIRST + 43)
Private  Const LVM_GETITEMSTATE As Long = (LVM_FIRST + 44)
Private  Const LVM_GETITEMTEXT As Long = (LVM_FIRST + 45)
Private  Const LVM_SETEXTENDEDLISTVIEWSTYLE As Long = (LVM_FIRST + 54)
Private  Const LVM_GETEXTENDEDLISTVIEWSTYLE As Long = (LVM_FIRST + 55)

Private  Const LVS_EX_GRIDLINES As Long = &H1
Private  Const LVS_EX_CHECKBOXES As Long = &H4
Private  Const LVS_EX_FULLROWSELECT As Long = &H20 'applies to report mode only

Private  Const LVIF_STATE As Long = &H8
Private  Const LVIS_STATEIMAGEMASK As Long = &HF000
 
Private  Const SW_NORMAL As Long = 1
Private  Const SW_SHOWMAXIMIZED As Long = 3
Private  Const SW_SHOWDEFAULT As Long = 10
Private  Const SW_SHOWNOACTIVATE As Long = 4
Private  Const SW_SHOWNORMAL As Long = 1

Private  Const SHGFI_TYPENAME As Long = &H400
Private  Const MAX_PATH As Long = 260

Private  Type LV_ITEM
    mask As Long
    iItem As Long
    iSubItem As Long
    state As Long
    stateMask As Long
    pszText As String
    cchTextMax As Long
    iImage As Long
    lParam As Long
    iIndent As Long
End Type
 
Private  Type LVCOLUMN
    mask As Long
    fmt As Long
    cx As Long
    pszText  As String
    cchTextMax As Long
    iSubItem As Long
    iImage As Long
    iOrder As Long
End Type

Private  Type SHFILEINFO
   hIcon As Long
   iIcon As Long
   dwAttributes As Long
   szDisplayName As String * MAX_PATH
   szTypeName As String * 80
End Type

Private  Declare Function SHGetFileInfo Lib "shell32" _
    Alias "SHGetFileInfoA" _
   (ByVal pszPath As String, _ 
    ByVal dwFileAttributes As Long, _ 
    psfi As SHFILEINFO, _ 
    ByVal cbSizeFileInfo As Long, _ 
    ByVal uFlags As Long) As Long
   
Private  Declare Function GetDesktopWindow Lib "user32" () As Long

Private  Declare Function ShellExecute Lib "shell32" _
    Alias "ShellExecuteA" _
   (ByVal hwnd As Long, _
    ByVal lpOperation As String, _
    ByVal lpFile As String, _
    ByVal lpParameters As String, _
    ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long

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 Function GetFileDescription(sFileName As String) As String
  
   Call SHGetFileInfo(sFileName, 0&, shinfo, Len(shinfo), SHGFI_TYPENAME)
   
   GetFileDescription = TrimNull(shinfo.szTypeName)

End Function


Private Function TrimNull(item As String) As String

  Dim pos As Integer
  
  pos = InStr(item, Chr$(0))
  If pos Then item = Left$(item, pos - 1)
  TrimNull = item
  
End Function


Private Sub chkCheckBox_Click()

   Dim state As Long
 
  'state will be true when the checkbox
  'style is 1 (checked) or False when
  'unchecked
   state = chkCheckBox.Value = 1
 
  'set the new listview style
   Call SendMessage(ListView1.hwnd, _
                    LVM_SETEXTENDEDLISTVIEWSTYLE, _
                    LVS_EX_CHECKBOXES, ByVal state)

End Sub


Private Sub chkGridLines_Click()

   Dim state As Long
 
  'state will be true when the checkbox
  'style is 1 (checked) or False when
  'unchecked
   state = chkGridLines.Value = 1
 
  'set the new listview style
   Call SendMessage(ListView1.hwnd, _
                    LVM_SETEXTENDEDLISTVIEWSTYLE, _
                    LVS_EX_GRIDLINES, ByVal state)

End Sub


Private Sub chkFullRowSelect_Click()

   Dim state As Long
 
  'state will be true when the checkbox
  'style is 1 (checked) or False when
  'unchecked
   state = chkSelectMode.Value = 1
 
  'set the new listview style
   Call SendMessage(ListView1.hwnd, _
                    LVM_SETEXTENDEDLISTVIEWSTYLE, _
                    LVS_EX_FULLROWSELECT, ByVal state)

End Sub


Private Sub cmdOpenSelected_Click()

   Dim hWndDesk As Long
   Dim sFile As String
   Dim params As String
   
   If ListView1.SelectedItem.Selected Then
   
      sFile = fPath & ListView1.SelectedItem.Text
      params = vbNullString
      
      hWndDesk = GetDesktopWindow()
      Call ShellExecute(hWndDesk, "Open", sFile, params, 0&, SW_SHOWNORMAL)
      
   End If

End Sub


Private Sub Combo1_Click()

  cmdSelect(1).Enabled = Len(fPath) > 0

End Sub


Private Sub SetCheck(hwnd As Long, lItemIndex As Long, bState As Boolean)

    Dim LV As LV_ITEM
    
    With LV
      .mask = LVIF_STATE
      .state = IIf(bState, &H2000, &H1000)
      .stateMask = LVIS_STATEIMAGEMASK
    End With
    
    Call SendMessage(hwnd, LVM_SETITEMSTATE, lItemIndex, LV)

End Sub


Private Sub cmdSetCheck_Click()

   Dim lvIndex As Long
   Dim lvCount As Long
   
   lvIndex = Val(Text1.Text)
   lvCount = ListView1.ListItems.Count - 1
   
   If lvIndex <= lvCount Then
      SetCheck ListView1.hwnd, lvIndex, True
   Else
      MsgBox "Select item 0 to " & lvCount & " only!"
   End If
   
End Sub


Private Sub cmdCheckInvert_Click()

   SetCheckInvertAll
   
End Sub


Private Sub cmdCheckAll_Click()

   SetCheckAllItems True

End Sub


Private Sub cmdUncheckAll_Click()

   SetCheckAllItems False
   
End Sub


Private Sub cmdOpenChecked_Click()

   Dim LV As LV_ITEM
   Dim state As Long
   Dim lvCount As Long
   Dim lvIndex As Long
   Dim hWndDesk As Long
   Dim sfile As String
   Dim params As String

   hWndDesk = GetDesktopWindow()
   lvCount = ListView1.ListItems.Count - 1
   lvIndex = 0
   
   Do
         
      state = SendMessage(ListView1.hwnd, LVM_GETITEMSTATE, lvIndex, ByVal LVIS_STATEIMAGEMASK)
      
      If state And &H2000& Then
           
         With LV
            .cchTextMax = MAX_PATH
            .pszText = Space$(MAX_PATH)
         End With
                 
         If SendMessage(ListView1.hwnd, LVM_GETITEMTEXT, lvIndex, LV) Then
            sfile = fPath & Left$(LV.pszText, InStr(LV.pszText, Chr$(0)) - 1)
            Call ShellExecute(hWndDesk, "Open", sfile, 0&, 0&, SW_SHOWNORMAL)
            DoEvents
         End If
            
      End If
         
      lvIndex = lvIndex + 1
   
   Loop Until lvIndex > lvCount

End Sub


Private Sub cmdGetChecked_Click()

   Dim i As Integer
   Dim r As Long
   Dim b As String
   Dim LV As LV_ITEM
   
   b = "The following ListView items are checked (0-based):" & vbCrLf & vbCrLf
   
   For i = 0 To ListView1.ListItems.Count - 1
   
      r = SendMessage(ListView1.hwnd, LVM_GETITEMSTATE, i, ByVal LVIS_STATEIMAGEMASK)
      
      If r And &H2000& Then
      
         With LV
            .cchTextMax = MAX_PATH
            .pszText = Space$(MAX_PATH)
         End With
   
         Call SendMessage(ListView1.hwnd, LVM_GETITEMTEXT, i, LV)
      
         b = b & "item " & CStr(i) & "  ( " & _
                 Left$(LV.pszText, InStr(LV.pszText, Chr$(0)) - 1) & " )" _
                 & vbCrLf
      End If
 
   Next
   
   If Len(b) > 0 Then MsgBox b

End Sub


Private Sub Form_Load()

   chkCheckBox.Value = 1
   chkFullRowSelect.Value = 1
   fPath = "d:\"
   Text1.Text = 0
   cmdOpenSelected.Enabled = False

End Sub


Private Sub ListView1_ItemClick(ByVal Item As ComctlLib.ListItem)

   cmdOpenSelected.Caption = "Open " & _
                             GetFileDescription(fPath$ & ListView1.SelectedItem.Text)
   cmdOpenSelected.Enabled = ListView1.SelectedItem.Selected = True

End Sub


Private Sub SetCheckAllItems(bState As Boolean)

   Dim LV As LV_ITEM
   Dim lvCount As Long
   Dim lvIndex As Long
   Dim lvState As Long
   
  'because IIf is less efficient than a
  'traditional If..Then..Else statement, just call
  'once to save the state mask to a local variable
   lvState = IIf(bState, &H2000, &H1000)
   
  'listview has 0 to count -1 items
   lvCount = ListView1.ListItems.Count - 1
   
   Do
         
      With LV
         .mask = LVIF_STATE
         .state = lvState
         .stateMask = LVIS_STATEIMAGEMASK
      End With
      
      Call SendMessage(ListView1.hwnd, LVM_SETITEMSTATE, lvIndex, LV)
      lvIndex = lvIndex + 1
   
   Loop Until lvIndex > lvCount
  
  'One could alternatively use "Loop Until r = False"
  'where r is the return value from SendMessage
  'as r is false when the call fails (no more to set).

End Sub


Private Sub SetCheckInvertAll()

   Dim LV As LV_ITEM
   Dim lvCount As Long
   Dim lvIndex As Long
   Dim r As Long
   
   lvCount = ListView1.ListItems.Count - 1
   
   Do
         
      r = SendMessage(ListView1.hwnd, LVM_GETITEMSTATE, lvIndex, ByVal LVIS_STATEIMAGEMASK)
      
      With LV
         .mask = LVIF_STATE
         .stateMask = LVIS_STATEIMAGEMASK
      
         If r And &H2000& Then
              'it is checked, so set the state
              'to 'unchecked'
               .state = &H1000
         Else: .state = &H2000
         End If
         
      End With
      
      Call SendMessage(ListView1.hwnd, LVM_SETITEMSTATE, lvIndex, LV)
      lvIndex = lvIndex + 1
   
   Loop Until lvIndex > lvCount

End Sub
 Comments
Run your project, enter a value into the textbox and press SetCheck. The 0-based list item will become checked.  See the introduction at the top of this page for info on the other button's features.

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter