Solved

ListView subitems

Posted on 1998-11-16
15
878 Views
Last Modified: 2013-12-25
I need to return the text of the subitem that the user clicked

so either on itemclick or column click i would like to be able to display the text of the clicked subitem.

My list view has 1 main item and 6 subitems

I am really stuck on this one!!

Thank you in advance
0
Comment
Question by:gbzhhu
  • 7
  • 3
  • 3
  • +2
15 Comments
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1488302
The columns have a left coordinate. This one can you compare with the coordinate clicked
Example:
Left coordinates are
    15,    35, 100, 125
Click position is 105. That means that column 3 is clicked.
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1488303
This is what I meant
Private Sub ListView1_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim CH As ColumnHeader
    Dim prevch As ColumnHeader
    For Each CH In ListView1.ColumnHeaders
        If (CH.Left < x) Then
            Set prevch = CH
        Else
            Exit For
        End If
    Next
    MsgBox prevch.Index
End Sub

0
 
LVL 12

Author Comment

by:gbzhhu
ID: 1488304
Mirkwood

What if user resizes a column header.  Sometimes it does not work
 I mean I pop up menu and it is ok then I enlarge one of the column headers and the pop menu is right next time.  Is there a way of knowing if user has resized a column header

thanks  
0
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1488305
I think this should work after resizing as well. I assume the left coordinates are updated in that case (you can verify). If not than this solution does not work.
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 1488306
Sorry Mirkwood

The solution does not work

Thank you for trying.  I still have no answer for this
0
 
LVL 2

Expert Comment

by:JiaH
ID: 1488307
The following works if the main item is not all out of the control.
    Dim itemX As ListItem
   
    Set itemX = ListView1.HitTest(30, y)
   
    If Not itemX Is Nothing Then
        Debug.Print itemX.Text
        Set itemX = Nothing
    End If

The left work is use the left of the item and the current x and the cloumwidth to get the subitem.

Hope this works.
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 1488308
JiaH

Your answer is rejected because it returns the main item and not the subitems

Thanks
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 2

Expert Comment

by:JiaH
ID: 1488309
I had told you how to get the subitem , look at this:
The left work is use the left of the item and the current x and the cloumwidth to get the subitem

Didn't can not works?
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 1488310
JiaH

I am sorry but I don't see how to do what you are telling me to do .  Can you give an example code.  I would appreciate that.


Thanks
0
 
LVL 2

Expert Comment

by:JiaH
ID: 1488311
Here you are the code:
Private Sub ListView1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim itemX As ListItem
     
    Set itemX = ListView1.HitTest(30, y)
     
    If Not itemX Is Nothing Then
        Dim nIndex As Integer, nItem As Integer
       
        For nIndex = 1 To ListView1.ColumnHeaders.Count
            With ListView1.ColumnHeaders(nIndex)
                If (x - itemX.Left - .Left) > 0 Then
                    If (x - itemX.Left - .Left) <= .Width Then
                        nItem = nIndex
                        Exit For
                    End If
                Else
                    nItem = nIndex - 1
                    Exit For
                End If
            End With
        Next
        If nItem = 0 Then nItem = ListView1.ColumnHeaders.Count
        Debug.Print itemX.Text, nItem
        Set itemX = Nothing
    End If
End Sub
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 1488312
JiaH

Your code solution does not work when the column header is resized and I actually found the problem.  There is a bug in column header control.  When it is resized it does not update the width properly.  There is an article about it in Microsoft's MSDN Knowledge Base.

Thanks for trying.  
0
 
LVL 7

Expert Comment

by:tward
ID: 1488313
Try this:

ListView1.ListItems(ListView1.SelectedItem.Index).SubItems(1)

Simply change the 1 to whichever subitem you want, just remember that they are 1 based.

I usually use this  in the DoubleClick Event but It should work in the MouseDown etc....
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 1488314
Sorry to reject this again, but it is either me speaking in alien language or people don't bother reading my question properly.

I want to return the text of the subitem the user clicked on ( no matter how many subitems I have got) and not subitems(1) nor the main item (ListView.selectedItem).

I have already got a way of returning it, using the colum header control but the column header control does not return its correct width property.  This is a Microsoft recognised bug.

Thanks anyway

0
 
LVL 15

Accepted Solution

by:
ameba earned 50 total points
ID: 1488315
This is e-mail by Peter F. Dubuque
Credits to him, points to me?
--
Yes, it *is* possible.  I figured this out a few months ago and I've been
thinking about posting this for a while but never got around to it...but
here you go.  The technique requires comctl32.dll version 4.70 (the
version shipped with IE3) or greater.

Drop a ListView onto your form (this example uses ListView1 for a name).
Add code to populate it with some ListItems & sub-items, and add the
following:

{declarations}

Option Explicit

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

Private Const LVM_FIRST = &H1000&
Private Const LVM_SUBITEMHITTEST = (LVM_FIRST + 57)

Private Const LVHT_NOWHERE = &H1
Private Const LVHT_ONITEMICON = &H2
Private Const LVHT_ONITEMLABEL = &H4
Private Const LVHT_ONITEMSTATEICON = &H8
Private Const LVHT_ONITEM = (LVHT_ONITEMICON Or LVHT_ONITEMLABEL Or _
    LVHT_ONITEMSTATEICON)

Private Type POINTAPI
    x           As Long
    y           As Long
End Type

Private Type LVHITTESTINFO
    pt          As POINTAPI
    lFlags      As Long
    lItem       As Long
    lSubItem    As Long
End Type

--------------------------------

Private Sub HitTestEx(x As Single, y As Single, tHitTest As LVHITTESTINFO)
   
    Dim lResult         As Long
    Dim lXCoord         As Long
    Dim lYCoord         As Long
   
'   x and y are in twips; convert them to pixels for the API call
    lXCoord = x / Screen.TwipsPerPixelX
    lYCoord = y / Screen.TwipsPerPixelY
   
    With tHitTest
        .lFlags = 0
        .lItem = 0
        .lSubItem = 0
        .pt.x = lXCoord
        .pt.y = lYCoord
    End With
   
    lResult = SendMessage(ListView1.hwnd, LVM_SUBITEMHITTEST, 0, tHitTest)

End Sub

----------------------------------

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

    Dim tHitTest        As LVHITTESTINFO
    Dim sLocation       As String
   
    HitTestEx x, y, tHitTest
   
    sLocation = "Item " & tHitTest.lItem + 1 & _
        ", SubItem " & tHitTest.lSubItem
   
    Select Case tHitTest.lFlags
        Case LVHT_NOWHERE
            sLocation = "Nowhere"
        Case LVHT_ONITEMICON
            sLocation = sLocation & ", on Icon"
        Case LVHT_ONITEMLABEL
            sLocation = sLocation & ", on Label"
        Case LVHT_ONITEMSTATEICON
            sLocation = sLocation & ", on State Icon"
    End Select
       
    MsgBox sLocation
   
End Sub

-----------------------------------------------

That's it.  If you click on the first column, .lSubItem = 0.  You can also
check the value of .lSubItem if you get a LVHT_NOWHERE flag; even if no
item was clicked, .lSubItem returns the column.  The other flags
(LVHT_ONITEMICON, _ONITEMLABEL and _ONITEMSTATEICON) give you more
detailed information about what part of the item was clicked on than you
get from the standard .HitTest method, and can be used in conjunction with
extended list view styles like LVS_EX_SUBITEMIMAGES or LVS_EX_CHECKBOXES
to tell whether the user clicked on a check box or not, or on the sub-item
icon.

One minor anomaly occurs with the LVHT_ONITEMLABEL flag.  If you click on
the first column, you get this flag only if you click inside the
ListItem's focus rectangle; clicking in the same row but outside gives you
LVHT_NOWHERE instead (just as you get with the default .HitTest method).
However, if you click on a sub-item, you get LVHT_ONITEMLABEL if you click
*anywhere* in that column (except on the sub-item icon, if there is any).


--
Peter F. Dubuque
0
 
LVL 12

Author Comment

by:gbzhhu
ID: 1488316
ameba

E X C E L L E N T!!

This is the solution I have been seeking for the last 2 months.  Thanks.  It works just perfect!!
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now