Jag har en ListView med ett antal rader och kolumner i ett program. Kan man ta reda på vilken "cell" som användaren klickar i? 1. Du måste nog använda dig av MouseClick (eller MouseDown?)-eventet och räkna ut vilken cell det gäller utifrån koordinaterna X och Y som kommer med eventet. Liten funktion som kanske hjälper dig:Div om ListView
Vilken rad man har klickat på är ju inget problem, så man skulle kunna kombinera det med att kolla vilken kolumn det är också. Men hur gör man det?
Sen skulle jag också vilja ha en bild i en av "cellerna". Är det möjligt?
ThomasSv: Div om ListView
2. VB6-Listviewen stödjer bara bilder i första kolumnen, men det kan möjligen gå genom att använda API:er och en massa extrakod. Själv skulle jag nog kolla på en tredjeparts-grid i stället...Sv: Div om ListView
<code>
Option Explicit
Private Const LVM_FIRST As Long = &H1000
Private Const LVM_HITTEST As Long = (LVM_FIRST + 18)
Private Const LVM_SUBITEMHITTEST As Long = (LVM_FIRST + 57)
Private Const LVHT_NOWHERE As Long = &H1
Private Const LVHT_ONITEMICON As Long = &H2
Private Const LVHT_ONITEMLABEL As Long = &H4
Private Const LVHT_ONITEMSTATEICON As Long = &H8
Private Const LVHT_ONITEM As Long = (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
flags As Long
iItem As Long
iSubItem As Long
End Type
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
Function HitTest(ListView As ListView, x As Single, y As Single) As Object
Dim Info As LVHITTESTINFO
Dim Item As ListItem
Info.flags = LVHT_ONITEM
With Info.pt
.x = (x \ Screen.TwipsPerPixelX)
.y = (y \ Screen.TwipsPerPixelY)
End With
Call SendMessage(ListView.hwnd, LVM_SUBITEMHITTEST, 0, Info)
If Info.iItem < 0 Then 'No hit
ElseIf Info.iSubItem Then 'Listsubitem hit
Set HitTest = ListView.ListItems(Info.iItem + 1).ListSubItems(Info.iSubItem)
Else 'Listitem hit
Set HitTest = ListView.ListItems(Info.iItem + 1)
End If
End Function
</code>
Exempel applikation:
<code>
Option Explicit
Private mMouseOver As Object
Private Sub Form_Load()
Dim x As Long
Dim y As Long
Dim Item As ListItem
ListView1.ColumnHeaders.Add
For x = 1 To 10
ListView1.ColumnHeaders.Add , , "Column " & x
Next
For y = 1 To 10
Set Item = ListView1.ListItems.Add(, , "Rad " & y)
For x = 1 To 10
Item.SubItems(x) = "(" & x & ", " & y & ")"
Next
Next
ListView1.View = lvwReport
ListView1.GridLines = True
ListView1.FullRowSelect = True
End Sub
Private Sub Form_Resize()
ListView1.Move ScaleLeft, ScaleTop, ScaleWidth, ScaleHeight
End Sub
Private Sub ListView1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Dim Temp As Object
Dim Item As ListItem
Dim SubItem As ListSubItem
Set Temp = HitTest(ListView1, x, y)
If Temp Is Nothing Then
ElseIf TypeOf Temp Is ListItem Then
Set Item = Temp
Debug.Print Item.Text
ElseIf TypeOf Temp Is ListSubItem Then
Set SubItem = Temp
Debug.Print SubItem.Text
End If
End Sub
Private Sub ListView1_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
Dim MouseOver As Object
Dim Item As ListItem
Dim SubItem As ListSubItem
Set MouseOver = HitTest(ListView1, x, y)
If Not mMouseOver Is MouseOver Then
If mMouseOver Is Nothing Then
ElseIf TypeOf mMouseOver Is ListItem Then
Set Item = mMouseOver
Item.Bold = False
ElseIf TypeOf mMouseOver Is ListSubItem Then
Set SubItem = mMouseOver
SubItem.Bold = False
End If
If MouseOver Is Nothing Then
ElseIf TypeOf MouseOver Is ListItem Then
Set Item = MouseOver
Item.Bold = True
ElseIf TypeOf MouseOver Is ListSubItem Then
Set SubItem = MouseOver
SubItem.Bold = True
End If
ListView1.Refresh
Set mMouseOver = MouseOver
End If
End Sub
</code>