设计要求树中节点内容是动态变化的。所以程序在Timer1中会用到以下两句:
TreeView1.Nodes(i).Image = 1
TreeView1.Nodes(i).Text = "aaa"
每次更新都会引起整个控件闪烁一下,有什么办法只让该节点的内容刷新,而不让整个控件刷新,避免闪烁。本想结合ValidateRect和InvalidateRect来做的,可是又没办法获得该节点的坐标。
TreeView1.Nodes(i).Image = 1
TreeView1.Nodes(i).Text = "aaa"
每次更新都会引起整个控件闪烁一下,有什么办法只让该节点的内容刷新,而不让整个控件刷新,避免闪烁。本想结合ValidateRect和InvalidateRect来做的,可是又没办法获得该节点的坐标。
在循环外将整个 TreeView 的刷新禁止,循环结束后再一次性刷新。
每次赋值,整个树都会先擦除,再重绘,从而闪烁。而我仅仅只是改变了一个节点的image和text属性,没必要整个树重绘吧,是我没用好treeview吗?
Private Sub Timer1_Timer()
Static b As Boolean
Dim nd As Node
b = Not b
For Each nd In TreeView1.Nodes
nd.Image = IIf(b, 1, 2)
nd.Text = Left$(nd.Text, 1) & IIf(b, "1", "0")
Next
End Sub
用你的代码试了,可是确实是闪的呀。你仔细感觉就能发现,它其实是先擦除再更新的。
可能所有节点都在变,你感觉不出闪的现象了。我只需要更改节点1的状态,这样闪的状态会更明显,
用以下代码你试一下:
Private Sub Timer1_Timer() '1秒一次
Static b As Boolean
Dim nd As Node
b = Not b
Set nd = TreeView1.Nodes(1)
nd.Image = IIf(b, 1, 2)
nd.Text = left$(nd.Text, 1) & IIf(b, "1", "0")
End Sub
treeview1.visible=true
'用它跳过这个跳(我们知道的正常的错):
On Error Resume Next
'将选定位置的图片加入Lst
Dim flecount As Long
Dim i As Long, j As Long, tmpEndN1 As Long, tmpEndN2 As Long
Dim TmpStr As String, DirGetMsg As String, DirNextDirMsg As String
Dim LstItm As ListItem, NowAddedDir() As String
'选定的每一个目录都要列举。定义动态数组,动态记录点过的目录,列过了就不列了。
tmpEndN1 = UBound(DirRecordCache())
ReDim Preserve NowAddedDir(0) As String '初始化监时数组。 For i = 0 To tmpEndN1
If InStr(DirRecordCache(i), TreeLst_NetPC.SelectedItem.Key) <> 0 Then Exit For
Next
If i > tmpEndN1 Then '一级缓存中没有访问痕迹
tmpEndN2 = UBound(DirRecord())
For i = tmpEndN2 To 0 Step -1
If InStr(DirRecord(i), TreeLst_NetPC.SelectedItem.Key) <> 0 Then Exit For
Next i
End If
If i < 0 Then '没有被访问记录,需要列举
'列举当前选中目录(盘符)下的一级子目录
'并记录在当选择目录
DirRecordCache(tmpEndN1) = TreeLst_NetPC.SelectedItem.Key
DirRecord(tmpEndN2) = TreeLst_NetPC.SelectedItem.Key
ReDim Preserve DirRecord(tmpEndN2 + 1) As String
If (tmpEndN1 + 1) <= 21 Then
ReDim Preserve DirRecordCache(tmpEndN1 + 1) As String
Else
ReDim Preserve DirRecordCache(0) As String
DirRecordCache(0) = ""
End If
'用dir()函数列出该机共享目录下的所有打印机录
DirGetMsg = Dir(CheckPath(TreeLst_NetPC.SelectedItem.Key), vbHidden + vbReadOnly + vbDirectory) ' 找寻第一项。
Do While DirGetMsg <> "" ' 开始循环。
' 跳过当前的目录及上层目录。
If DirGetMsg <> "." And DirGetMsg <> ".." Then
' 使用位比较来确定 MyName 代表一目录。
If (GetAttr(CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg) And vbDirectory) = vbDirectory Then
' 如果它是一个目录,将其名称显示出来。
For i = 0 To UBound(NowAddedDir())
If InStr(NowAddedDir(i), CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg) <> 0 Then
Exit For
End If
Next i
If i > UBound(NowAddedDir()) Then
' 如果它是一个目录,将其名称显示出来。
Me.TreeLst_NetPC.Nodes.Add TreeLst_NetPC.SelectedItem.Key, tvwChild, CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg, DirGetMsg
'让有下级目录的显示+号。列一个出来。省时间
DirNextDirMsg = Dir(CheckPath(CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg), vbHidden + vbReadOnly + vbDirectory)
ReDim Preserve NowAddedDir(j) As String
NowAddedDir(j) = CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg
j = j + 1
Do While DirNextDirMsg <> ""
If DirNextDirMsg <> "." And DirNextDirMsg <> ".." Then
' 使用位比较来确定 MyName 代表一目录。
If (GetAttr(CheckPath(CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg) & DirNextDirMsg) And vbDirectory) = vbDirectory Then
' 如果它是一个目录,将其名称显示出来。
Me.TreeLst_NetPC.Nodes.Add CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg, tvwChild, CheckPath(CheckPath(TreeLst_NetPC.SelectedItem.Key) & DirGetMsg) & DirNextDirMsg, DirNextDirMsg
DirGetMsg = Dir(CheckPath(TreeLst_NetPC.SelectedItem.Key), vbHidden + vbReadOnly + vbDirectory) ' 找寻第一项。
Exit Do
End If
End If
DirNextDirMsg = Dir ' 查找下一个目录。
If DirNextDirMsg = "" Then
DirGetMsg = Dir(CheckPath(TreeLst_NetPC.SelectedItem.Key), vbHidden + vbReadOnly + vbDirectory) ' 找寻第一项。
End If
Loop
End If
End If
End If
DirGetMsg = Dir ' 查找下一个目录。
Loop
End If
'Me.Text2.Text = CheckPath(Me.TreeLst_NetPC.SelectedItem.Key)直接用会有好些问题..HOHO..
树已建好,只是节点上显示的图像和文字要变化。如果只是变化image,我改成这样倒是可以忍受:
Private Sub Timer1_Timer() '1秒一次
Static b As Boolean
Dim nd As Node
b = Not b
Set nd = TreeView1.Nodes(1)
nd.Image = IIf(b, 1, 2)
'nd.Text = left$(nd.Text, 1) & IIf(b, "1", "0")
ValidateRectBynum TreeView1.hWnd, 0
InvalidateRecBynum TreeView1.hWnd, 0, 0
UpdateWindow TreeView1.hwnd
End Sub但如果变化的是Text属性,就不行了:
Private Sub Timer1_Timer() '1秒一次
Static b As Boolean
Dim nd As Node
b = Not b
Set nd = TreeView1.Nodes(1)
'nd.Image = IIf(b, 1, 2)
nd.Text = left$(nd.Text, 1) & IIf(b, "1", "0")
ValidateRectBynum TreeView1.hWnd, 0
InvalidateRecBynum TreeView1.hWnd, 0, 0
UpdateWindow TreeView1.hwnd
End Sub
为什么ValidateRectBynum会来不及屏蔽text属性的变化呢?
欢迎大家继续探讨。