Microsoft's Treeview control does not support highlighting the
currently selected Node's text. While you can highlight a node by running
code in the Node's Click event, the previously highlighted Node will not clear.
Using the SendMessage API, it's possible to retrieve the current
settings of a Node, and by iterating over all the nodes, if the Bold property is
set to be true for a Node, we can force the Node to reset and repaint normally.
To view this sample, place a Treeview (Version 6) on a form, and name
it tvwTest. Copy the following code in the form's class module.
Private Type TV_ITEM
mask As Long
hItem As Long
state As Long
stateMask As Long
pszText As String
cchTextMax As Long
iImage As Long
iSelectedImage As Long
cChildren As Long
lParam As Long
End Type
Private Declare Function apiSendMessage _
Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) _
As Long
Private Const TVIS_BOLD As Long = &H10
Private Const TV_FIRST As Long = &H1100
Private Const TVM_GETITEM As Long = (TV_FIRST + 12)
Private Const TVIF_HANDLE = &H10
Private Const TVGN_ROOT = &H0
Private Const TVIF_CHILDREN = &H40
Private Const TVM_GETNEXTITEM = (TV_FIRST + 10)
Private Const TVGN_CHILD = &H4
Private Const TVIF_STATE = &H8
Private Const TVM_SETITEM = (TV_FIRST + 13)
Private Const TVGN_NEXT = &H1
Private Const TVGN_CARET = &H9
Private mobjLastNode As Node
Private mlngBackColor As Long
Private Sub Form_Load()
Dim objNode As Node
Dim i As Integer
For i = 1 To 10
Set objNode = tvwTest.Nodes.Add(, , "r" & i, "ANode" & i)
Next
End Sub
Private Sub sResetItems(hWnd As Long, hItem As Long)
Dim tvi As TV_ITEM
Dim hItemChild As Long
Dim objNode As Node
If hItem = 0 Then
hItem = apiSendMessage(hWnd, _
TVM_GETNEXTITEM, _
TVGN_ROOT, _
ByVal 0&)
End If
If Not mobjLastNode Is Nothing Then
With mobjLastNode
.ForeColor = vbBlack
.BackColor = mlngBackColor
End With
End If
Do While Not hItem = 0
tvi.hItem = hItem
tvi.mask = TVIF_CHILDREN Or TVIF_STATE
tvi.stateMask = TVIS_BOLD
Call apiSendMessage(hWnd, _
TVM_GETITEM, _
0, _
tvi)
If tvi.state And TVIS_BOLD = TVIS_BOLD Then
tvi.state = tvi.state And Not TVIS_BOLD
Call apiSendMessage( _
hWnd, _
TVM_SETITEM, _
0, _
tvi)
End If
If (tvi.cChildren) Then
hItemChild = apiSendMessage( _
hWnd, _
TVM_GETNEXTITEM, _
TVGN_CHILD, _
ByVal hItem)
Call sResetItems(hWnd, hItemChild)
End If
hItem = apiSendMessage(hWnd, _
TVM_GETNEXTITEM, _
TVGN_NEXT, _
ByVal hItem)
Loop
End Sub
Private Sub tvwTest_NodeClick(ByVal Node As Object)
Call sResetItems(Me.tvwTest.hWnd, 0)
With Node
.Bold = True
.ForeColor = vbBlue
mlngBackColor = .BackColor
.BackColor = vbYellow
End With
Set mobjLastNode = Node
End Sub
|