经过一番研究和几个小时的编码,我终于自己写出了解决方案。
我需要添加一个ImageList,将其与TreeView关联,并添加三种状态下的复选框图像。在此过程中,Google图片搜索为我节省了一些时间 :)
Private Enum CheckboxEnum
Unchecked = 1
Checked = 2
Partial = 3
End Enum
Private Sub objTreeView_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As stdole.OLE_XPOS_PIXELS, ByVal y As stdole.OLE_YPOS_PIXELS)
Const CHECKBOX_WIDTH As Integer = 195
Dim objNode As Node
Set objNode = objTreeView.HitTest(x, y)
If objNode Is Nothing Then
Else
Dim intX As stdole.OLE_XPOS_PIXELS
For intX = x To 0 Step -15
If Not objNode Is objTreeView.HitTest(intX, y) Then
If x <= intX + CHECKBOX_WIDTH Then
Select Case objNode.Image
Case CheckboxEnum.Unchecked:
objNode.Image = CheckboxEnum.Checked
Case Else:
objNode.Image = CheckboxEnum.Unchecked
End Select
Call CheckTreeNodes(objTreeView, objNode, objNode.Image)
Call UpdateParentNodes(objTreeView, objNode)
Else
End If
Exit For
End If
Next
End If
End Sub
Private Sub CheckTreeNodes(ByRef tv As TreeView, ByRef nodNode As Node, ByVal Value As CheckboxEnum)
Dim lngIndex As Long
If nodNode.Children > 0 Then
lngIndex = nodNode.Child.Index
Call CheckTreeNodes(tv, tv.Nodes(lngIndex), Value)
Do While lngIndex <> nodNode.Child.LastSibling.Index
lngIndex = tv.Nodes(lngIndex).Next.Index
Call CheckTreeNodes(tv, tv.Nodes(lngIndex), Value)
Loop
End If
nodNode.Image = Value
End Sub
Private Sub CountChildNodes(ByRef tv As TreeView, ByRef nodNode As Node, ByRef lngChecked As Long, ByRef lngUnchecked As Long)
Dim lngIndex As Long
If nodNode.Children > 0 Then
lngIndex = nodNode.Child.Index
Call CountChildNodes(tv, tv.Nodes(lngIndex), lngChecked, lngUnchecked)
Do While lngIndex <> nodNode.Child.LastSibling.Index
lngIndex = tv.Nodes(lngIndex).Next.Index
Call CountChildNodes(tv, tv.Nodes(lngIndex), lngChecked, lngUnchecked)
Loop
Else
Select Case nodNode.Image
Case CheckboxEnum.Checked:
lngChecked = lngChecked + 1
Case CheckboxEnum.Unchecked:
lngUnchecked = lngUnchecked + 1
End Select
End If
End Sub
Private Sub UpdateParentNodes(ByRef tv As TreeView, ByRef nodNode As Node)
Dim lngIndex As Long
Dim nodParent As Node
Dim lngChecked As Long, lngUnchecked As Long
If nodNode.Parent Is Nothing Then Exit Sub
Set nodParent = nodNode
Do While Not nodParent.Parent Is Nothing
Set nodParent = nodParent.Parent
lngUnchecked = 0
lngChecked = 0
Call CountChildNodes(tv, nodParent, lngChecked, lngUnchecked)
If lngUnchecked = 0 And lngChecked > 0 Then
nodParent.Image = CheckboxEnum.Checked
ElseIf lngUnchecked > 0 And lngChecked > 0 Then
nodParent.Image = CheckboxEnum.Partial
Else
nodParent.Image = CheckboxEnum.Unchecked
End If
Loop
End Sub