Hat ein Knoten in einem TreeView-Steuerelement Unterknoten, wird dieser Knoten mit einem Doppelklick darauf geöffnet. Manchmal ist es jedoch wünschenswert, einen Doppelklick auf einen Knoten abweichend von diesem Standard-Verhalten mit einer anderen Funktion zu belegen.
Zum einen müssen Sie dazu feststellen können, ob der Doppelklick auf einem Knoten oder im freien Raum erfolgt ist. Zum anderen müssen Sie im Expand- und im Collapse-Ereignis unterscheiden können, ob der Knoten tatsächlich expandieren bzw. kollabieren soll, weil das Verzweigungssymbol (+/-) angeklickt oder die Plus- bzw. Minus-Taste bzw. die Rechts- oder Linkspfeil-Taste des Ziffernblocks betätigt worden ist.
Die Position und damit den betreffenden Knoten ermitteln Sie im MouseDown-Ereignis mittels eines Aufrufs der Methode HitTest des TreeView-Steuerelements. Das Ergebnis des Aufrufs wird in einer modulweiten Variablen (mNode) festgehalten. Im DblClick-Ereignis prüfen Sie, ob die Variable einen Knoten enthält. Ist das der Fall, können Sie hier die für den Doppelklick gewünschte Aktion ausführen.
Um ausschließlich im Fall des Doppelklicks auf einen Knoten zu verhindern, dass dieser expandiert oder kollabiert, setzen Sie im MouseDown-Ereignis und auch im KeyDown-Ereignis für die KeyCodes vbKeyAdd, vbKeySubtract, vbKeyLeft und vbKeyRight eine ebenfalls modulweit deklarierte Merkvariable (mMouseKey) auf True. Im MouseUp- und KeyUp-Ereignis setzen Sie diese Variable wieder auf False.
Bei einem Klick auf das Verzweigungssymbol oder bei der Betätigung einer der genannten Tasten wird das Expand- bzw. das Collapse-Ereignis immer zwischen dem jeweiligen Down- und Up-Ereignis ausgelöst. Bei einem Doppelklick erfolgt das Expand- oder das Collapse-Ereignis dagegen erst nach dem ersten MouseUp-Ereignis (ein Doppelklick umfasst die Ereignisreihenfolge MouseDown, MouseUp und noch einmal MouseUp). Bei einem von einem Doppelklick ausgelösten Expand- oder Collapse-Ereignis ist also die Merkvariable mMouseKey bereits wieder auf False gesetzt, so dass Sie bequem die Auslösung durch einen Doppelklick herausfiltern können.
Allerdings können Sie das Expandieren bzw. Kollabieren des Knotens nicht wirklich unterdrücken. Sie können aber die jeweilige Aktion auf der Stelle wieder rückgängig machen. Im Expand-Ereignis lassen Sie den Knoten sofort wieder kollabieren und im Collapse-Ereignis sofort wieder expandieren. Das leichte Flackern können Sie unterdrücken, indem Sie im MouseDown-Ereignis die API-Funktion LockWindowUpdate mit dem Fenster-Handle des TreeView-Steuerelements und im MouseUp-Ereignis mit dem Wert 0 aufrufen.
Damit jedoch keine endlose Wechselwirkung (Rekursion) zwischen Expand- und Collapse-Ereignis eintritt, benötigen Sie eine weitere Hilfsvariable (mLock), die Sie in beiden Ereignissen zunächst auf True und nach der Aktion wieder auf False setzen. Zu Beginn der beiden Ereignisprozeduren prüfen Sie, ob die Variable gesetzt ist. Ist dies der Fall, wird die Ereignisprozedur sofort wieder verlassen, ohne die verkettete Aktion auszuführen.
Das NodeClick-Ereignis (und beim TreeView-Steuerelement der Version 6 auch das NodeCheck-Ereignis) bleibt von dem ganzen Verfahren völlig unberührt und funktioniert wie gewohnt.
Private Declare Function LockWindowUpdate Lib "user32" _
(ByVal hwndLock As Long) As Long
Private mMouseKey As Boolean
Private mLock As Boolean
Private mNode As Node
Private Sub TreeView1_Collapse(ByVal Node As ComctlLib.Node)
If mLock Then
Exit Sub
End If
mLock = True
If Not mMouseKey Then
Node.Expanded = True
End If
mLock = False
End Sub
Private Sub TreeView1_DblClick()
If Not (mNode Is Nothing) Then
Debug.Print "DblClick - " & mNode.Text
Else
Debug.Print "DblClick - Irgendwo"
End If
End Sub
Private Sub TreeView1_Expand(ByVal Node As ComctlLib.Node)
If mLock Then
Exit Sub
End If
mLock = True
If Not mMouseKey Then
Node.Expanded = False
End If
mLock = False
End Sub
Private Sub TreeView1_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case vbKeyAdd, vbKeySubtract, vbKeyLeft, vbKeyRight
mMouseKey = True
End Select
End Sub
Private Sub TreeView1_KeyUp(KeyCode As Integer, Shift As Integer)
mMouseKey = False
End Sub
Private Sub TreeView1_MouseDown(Button As Integer, _
Shift As Integer, x As Single, y As Single)
LockWindowUpdate TreeView1.hWnd
mMouseKey = True
Set mNode = TreeView1.HitTest(x, y)
End Sub
Private Sub TreeView1_MouseUp(Button As Integer, _
Shift As Integer, x As Single, y As Single)
mMouseKey = False
LockWindowUpdate 0&
End Sub
|