ListView SubItem Click

in Visual Basic®



by Rick Meyer       Home

Interestingly ListView does not have a built in way to tell if a SubItem has been clicked. This very brief VB project demonstrates how to use the SendMessage API to click on SubItems.

Also, if you click the first column slightly off the text (to the right) no click event happens unless you set ListView.FullRowSelect = True

If you search the program you will find that these are all the ListView commands:

ListView1.Move 120, 120, 4440, 2500 'Position the control on the form
ListView1.ColumnHeaders.Add , , "Column", 1000 'Add the Column Headers
Set l = ListView1.ListItems.Add(, , "Item") 'Add a ListItem
l.ListSubItems.Add , , "SubItem" 'Add the SubItems

    Instructions for Building this Project:

1. Start a new standard exe.
2. On Form1 put a Label named Label1.
3. On Form1 put a ListView Control named ListView1.
4. Set the ListView1.View property to 3-lvwReport.
5. Set the ListView1.LabelEdit property to Manual.
6. Set the ListView1.FullRowSelect property to True.

There is no need to position or size the above controls
on the form since that is all done in the Form_Load.

To find the ListView Control click on the VB Menu->Project->Components and select Microsoft Windows Common Controls 6. After you click OK the ListView Control (and some others) will appear in the toolbar usually on the left of the VB IDE (Integrated Development Environment).
Now you are ready for the code. Select all of the following code (by clicking on the word 'Option' three times) and copy it to the clipboard [Ctrl][Insert]. Then paste it into the code window of Form1 with [Shift][Insert]. Variable Key
% As Integer
& As Long
! As Single
# As Double
$ As String
Option Explicit

'=======================================================
'                    Declarations
'=======================================================
Private Type lvwMsgInfo
    x As Long
    y As Long
    Flgs As Long
    Itm As Long
    SubItm As Long
End Type

Private Declare Function SendMessage _
    Lib "user32" Alias "SendMessageA" ( _
        ByVal hwnd As Long, _
        ByVal lMsg As Long, _
        ByVal wParam As Long, _
        lParam As Any) As Long

Dim lvwMsg As lvwMsgInfo

'=======================================================
'                    Procedures
'=======================================================
Private Sub ListView1_MouseDown(Button As Integer, _
        Shift As Integer, x As Single, y As Single)

    'Setup the API call
    lvwMsg.x = x / Screen.TwipsPerPixelX
    lvwMsg.y = y / Screen.TwipsPerPixelY
    
    'Make the API call
    SendMessage ListView1.hwnd, 4153, 0, lvwMsg
    
    'Test for a valid click
    If lvwMsg.Flgs And 14 Then
        'The Item returned is 0 based and
        ' there is no 0 ListItem - so + 1
        Label1 = "Item " & CStr(lvwMsg.Itm + 1)
        
        'There is no such thing as SubItem 0
        If lvwMsg.SubItm Then
            Label1 = Label1 & ", SubItem " _
                        & CStr(lvwMsg.SubItm)
        End If
    End If
End Sub

Private Sub Form_Load()
    'Position and size the controls
    Move 1000, 1000, 4800, 3600
    ListView1.Move 120, 120, 4440, 2500
    Label1.Move 720, 2760, 2655, 375
    
    Dim j%, k%
    Dim l As ListItem

    'Add the ListView ColumnHeaders
    For j = 1 To 6
        ListView1.ColumnHeaders.Add , , _
                "Column " & CStr(j), 1000
    Next
    
    For j = 1 To 6
        'Add a ListItem
        Set l = _
        ListView1.ListItems.Add(, , "Item " & CStr(j))
        
        'Add the SubItems
        For k = 1 To 5
            l.ListSubItems.Add , , "SubItem " & CStr(k)
        Next
    Next
End Sub