ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 06.11.2000

Diese Seite wurde zuletzt aktualisiert am 06.11.2000
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Bunte Knoten

Zurück...


Anzeige

(-hg) mailto:hg_tvwforecolor@aboutvb.de

Die Textfarbe der Knoten können Sie beim TreeView-Steuerelement der Microsoft Common Controls ab Version 6 über die Eigenschaft ForeColor für jeden Knoten einzeln beliebig festlegen. Beim TreeView-Steuerelement der Version 5 und früher fehlt diese Eigenschaft noch - und damit überhaupt die Möglichkeit, die Textfarben der Knoten zu beeinflussen. Allerdings können Sie in der Version 5 über die Nachricht MSDN Library - API TVM_SETTEXTCOLORTVM_SETTEXTCOLOR die Textfarbe aller Knoten auf einmal setzen. Der Versuch, dies wiederum auch beim TreeView-Steuerelement der Version 6 zu erreichen, schlägt jedoch fehl, da das Steuerelement die Textfarben offensichtlich eigenständig für jeden Knoten einzeln verwaltet.

Befassen wir uns zunächst mit dem recht einfachen Setzen der Textfarbe für alle Knoten bei einem TreeView-Steuerelement der Version 5. Wie bereits erwähnt, senden Sie die Nachricht TVM_SETTEXTCOLOR an das Steuerelement und übergeben dabei der API-Funktion MSDN Library - API SendMessageSendMessage im Parameter lParam den neuen RGB-Farbwert. Damit Sie auch die Konstanten der Systemfarben problemlos verwenden können, wird dem Aufruf noch die API-Funktion MSDN Library - API OleTranslateColorOleTranslateColor vorgeschaltet, die eine Systemfarben-Konstante gegebenenfalls in einen RGB-Farbwert übersetzt (siehe Systemfarben-Dolmetscher"Systemfarben-Dolmetscher"). Den Aufruf der beiden API-Funktionen verpacken wir in die handliche Hilfsfunktion TreeViewSetForeColor5, die als kleines Extra noch den zuvor aktuellen Farbwert zurückgibt.

Private Declare Function OleTranslateColor Lib "oleaut32.dll" _
(ByVal lOleColor As Long, ByVal lHPalette As Long, _
 ByRef lColorRef As Long) As Long
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

Public Function TreeViewSetForeColor5(TreeView As TreeView, _
 ByVal ForeColor As OLE_COLOR) As OLE_COLOR

  Const TVM_SETTEXTCOLOR = &H111E

  OleTranslateColor ForeColor, 0&, ForeColor
  TreeViewSetForeColor5 = SendMessage(TreeView.hwnd, _
   TVM_SETTEXTCOLOR, 0&, ByVal ForeColor)
End Function

Das das TreeView-Steuerelement der Version 6 nicht auf die Nachricht TVM_SETTEXTCOLOR reagiert, bleibt Ihnen nichts anderes übrig, als in einer Schleife jedem Knoten die neue Farbe einzeln zuzuweisen. Damit das Steuerelement bei einer größeren Anzahl sichtbarer Knoten nicht flackert (die Darstellung wird jedes Mal aktualisiert), wird die Aktualisierung mit dem Aufruf der API-Funktion MSDN Library - API LockWindowUpdateLockWindowUpdate vor dem Beginn der Schleife aus- und anschließend wieder eingeschaltet. Auch dies verpacken wir wieder in eine Hilfsprozedur, die wir zur Unterscheidung TreeViewSetForeColor6 nennen.

Private Declare Function LockWindowUpdate Lib "user32" _
 (ByVal hwndLock As Long) As Long

Public Sub TreeViewSetForeColor6(TreeView As TreeView, _
 ByVal ForeColor As OLE_COLOR)

  Dim nNode As Node
  
  With TreeView
    LockWindowUpdate .hwnd
    For Each nNode In .Nodes
      nNode.ForeColor = ForeColor
    Next
    LockWindowUpdate 0&
  End With
End Sub

Falls Sie gerne eine Hilfsfunktion hätten, die beide TreeView-Versionen "verarzten" kann - kein Problem. Die Hilfsfunktion TreeViewSetForeColor prüft zunächst anhand des Vorhandenseins der Eigenschaft CheckBoxes (die ja erst ab Version 6 zur Verfügung steht), um welche Version es sich handelt, und ruft dementsprechend eine der zuvor beschriebenen Funktionen auf.

Public Function TreeViewSetForeColor(TreeView As TreeView, _
 ByVal ForeColor As OLE_COLOR) As OLE_COLOR

  Dim nTest As Boolean
  Dim nForeColor As Long
  
  On Error Resume Next
  nTest = TreeView.Checkboxes
  If Err.Number Then
    On Error GoTo 0
    TreeViewSetForeColor5 TreeView, ForeColor
  Else
    On Error GoTo 0
    TreeViewSetForeColor6 TreeView, ForeColor
  End If
End Function

Bezüglich des TreeView-Steuerelements der Version 5 können Sie nun glücklich und zufrieden sein. Doch die Lösung für die Version 6 ist ein wenig rabiat und daher unbefriedigend. Denn das Ändern der Textfarbe bei sämtlichen Knoten bügelt schließlich auch für einzelne Knoten bereits individuell vergebene Textfarben weg. Außerdem hat sie den Nachteil, dass Sie die Prozedur erst nach dem Einfügen von Knoten verwenden können - denn: ohne Knoten keine Änderung. Und Sie müssen die gewünschte Standard-Textfarbe separat in einer Variablen ablegen, um jeden später neu hinzugefügten Knoten in dieser Farbe einfärben zu können. Bei der Version 5 stellt beides kein Problem dar: Wenn Sie die Farbe für ein leeres TreeView-Steuerelement einmal gesetzt haben, nimmt jeder danach eingefügte Knoten automatisch diese Textfarbe an.

Um zu einer einigermaßen praktikablen und komfortablen Lösung für die Version 6 zu gelangen, müssen wir ein wenig mehr Aufwand treiben. Da Sie unter Umständen für mehrere TreeView-Steuerelemente unterschiedliche Textfarben verwalten wollen, ist der Einsatz einer Klasse naheliegend. Einer Instanz dieser Klasse (wir nennen sie TvwForeColors) übergeben Sie einmal in der Init-Methode ein bestimmtes TreeView-Steuerelement und optional eine Standard-Textfarbe (die auf die Systemfarbe vbWindowText voreingestellt ist). Im letzten, ebenfalls optionalen Parameter der Init-Methode (ValidateByNode) geben Sie an, ob für jeden Knoten vor dem Ändern seiner Textfarbe ein Ereignis ausgelöst werden soll, bei dem Sie die Änderung für den jeweiligen Knoten unterdrücken können.

Private pForeColor As Long
Private pTreeView As TreeView
Private pValidateByNode As Boolean

Private Sub Class_Initialize()
  pForeColor = vbWindowText
End Sub

Public Sub Init(TreeView As TreeView, _
 Optional ByVal ForeColor As OLE_COLOR = vbWindowText, _
 Optional ByVal ValidateByNode As Boolean)

  Set pTreeView = TreeView
  pForeColor = ForeColor
  pValidateByNode = ValidateByNode
End Sub

Private Sub Class_Terminate()
  Set pTreeView = Nothing
End Sub

Das übergebene TreeView-Element können Sie über die Eigenschaft TreeView auslesen. So brauchen Sie gegebenenfalls nur die Instanz der Klasse in Ihrem Projekt mitzuführen, da Sie das Steuerelement selbst jederzeit über diese Eigenschaft ansprechen können:

Public Property Get TreeView() As TreeView
  Set TreeView = pTreeView
End Property

Auch die gesetzte TextFarbe können Sie über eine Eigenschaft auslesen:

Public Property Get ForeColor() As OLE_COLOR
  ForeColor = pForeColor
End Property

Nun schauen wir uns noch kurz das erwähnte Ereignis ValidateNode an. Es ist wie folgt deklariert:

Public Event ValidateNode(Node As Node, _
 ByVal NewForeColor As OLE_COLOR, NoChange As Boolean)

Hier wird der Knoten übergeben, dessen Textfarbe in die im zweiten Parameter übergeben neue Textfarbe geändert werden soll. Setzen Sie den Rückgabe-Parameter NoChange auf True, unterbleibt die Änderung für diesen Knoten. Sie können die Auslösung des Ereignisses jederzeit über die Eigenschaft ValidateByNode ein- und ausschalten:

Public Property Get ValidateByNode() As Boolean
  ValidateByNode = pValidateByNode
End Property

Public Property Let ValidateByNode( _
 ByVal New_ValidateByNode As Boolean)

  pValidateByNode = New_ValidateByNode
End Property

Damit Sie die Textfarbe nicht für jeden neu hinzugefügten Knoten selbst einzeln setzen müssen, können Sie neue Knoten über die Methode Add hinzufügen. Die Parameter sind die gleichen wie bei der originalen Add-Methode der Nodes-Collection des TreeView-Steuerelements. Hinzugekommen ist lediglich der optionale Parameter ForeColor, in dem Sie eine für den Knoten spezifische Textfarbe angeben können. Lassen Sie den Parameter weg, erhält der Knoten automatisch die für das ganze Steuerelement gesetzte Textfarbe. Als Rückgabewert der Funktion erhalten Sie den neu einfügten Knoten.

Public Function Add(Optional Relative As Variant, _
 Optional Relationship As Variant, Optional Key As Variant, _
 Optional Text As Variant, Optional Image As Variant, _
 Optional SelectedImage As Variant, _
 Optional ForeColor As Variant) As Node

  Dim nNode As Node
  
  On Error GoTo Add_Error
  With pTreeView
    Set nNode = .Nodes.Add(Relative, Relationship, Key, Text, _
     Image, SelectedImage)
    If Not (nNode Is Nothing) Then
      If IsMissing(ForeColor) Then
        nNode.ForeColor = pForeColor
      Else
        nNode.ForeColor = ForeColor
      End If
    End If
  End With
  Set Add = nNode
  Exit Function
  
Add_Error:
  Err.Raise Err.Number, "TvwForeColors.Add", Err.Description
End Function

Kommen wir nun zum nachträglichen Ändern der Textfarbe(n). Zum einen können Sie die allgemeine Textfarbe über die Methode SetForeColor setzen (sie ist ausnahmsweise nicht als Property Let-Prozedur angelegt, da Sie einen zusätzlichen Parameter benötigt). Sie übergeben die neue Textfarbe und geben im optionalen Parameter SetMode an, ob der neue Wert der Textfarbe nur in die interne Variable pForeColor übernommen werden soll und ob die Knoten vorläufig unverändert bleiben sollen (Enumerationswert tfcSetModeNone), oder ob nur die Knoten die neue Textfarbe erhalten sollen, die zurzeit die alte Textfarbe haben (Enumerationswert tfcSetModeCorresponding; die Methode Replacecolor wird weiter unten beschrieben), oder ob alle Knoten die neue Textfarbe unbeachtet ihrer aktuellen Textfarbe erhalten sollen (Enumerationswert tfcSetAll).

Private Declare Function LockWindowUpdate Lib "user32" _
 (ByVal hwndLock As Long) As Long

Public Enum TvwForeColorsSetModeConstants
  tfcSetModeNone
  tfcSetModeCorresponding
  tfcSetAll
End Enum

Public Sub SetForeColor(ByVal New_ForeColor As OLE_COLOR, _
 Optional SetMode As TvwForeColorsSetModeConstants = tfcSetAll)
  Dim nNode As Node
  Dim nNoChange As Boolean
  
  Select Case SetMode
    Case tfcSetModeNone
      pForeColor = New_ForeColor
    Case tfcSetModeCorresponding
      ReplaceForeColor , New_ForeColor, True
    Case tfcSetAll
      pForeColor = New_ForeColor
      With pTreeView
        LockWindowUpdate .hwnd
        If pValidateByNode Then
          For Each nNode In .Nodes
            nNoChange = False
            RaiseEvent ValidateNode(nNode, pForeColor, nNoChange)
            If Not nNoChange Then
              nNode.ForeColor = pForeColor
            End If
          Next
        Else
          For Each nNode In .Nodes
            nNode.ForeColor = pForeColor
          Next
        End If
        LockWindowUpdate 0&
      End With
  End Select
End Sub

Die Methode ReplaceColor ermöglicht eine selektive Änderung der Textfarbe. Alle Knoten einer bestimmten Farbe erhalten eine neue Farbe. Hier übergeben Sie optional die zu ändernde Textfarbe (OldForeColor) und ebenfalls optional die neue Textfarbe (NewForeColor). Lassen Sie versehentlich beide Parameter weg, wird ein Fehler ausgelöst (tfcErrNoArguments). Lassen Sie den ersten Parameter weg, wird die Textfarbe bei den Knoten geändert, die aktuell die allgemeine als Eigenschaft eingestellte Textfarbe haben. Wenn Sie dann im letzten optionalen Parameter SetNewForeColor den Wert True übergeben, wird die neue Farbe als künftige allgemeine Textfarbe, also als Wert der Eigenschaft ForeColor übernommen. Lassen Sie die neue Farbe weg, wird als neue Farbe die eingestellte allgemeine Textfarbe übernommen. Sollten nun beide Farben identisch sein, wird der Fehler tfcErrSameColors ausgelöst, und es erfolgt keine Änderung.

Public Enum TvwForeColorsErrorConstants
  tfcErrNoArguments = vbObjectError + 10001
  tfcErrSameColors = vbObjectError + 10002 
End Enum

Public Sub ReplaceForeColor(Optional ByVal OldForeColor As Variant, _
 Optional ByVal NewForeColor As Variant, _
 Optional ByVal SetNewForeColor As Boolean)

  Dim nOldForeColor As Long
  Dim nNewForeColor As Long
  Dim nNode As Node
  Dim nNoChange As Boolean
  
  If IsMissing(OldForeColor) And IsMissing(NewForeColor) Then
    Err.Raise tfcErrNoArguments, "TvwForeColors.ReplaceForeColor"
  Else
    If IsMissing(OldForeColor) Then
      nOldForeColor = pForeColor
    Else
      nOldForeColor = OldForeColor
    End If
    If IsMissing(NewForeColor) Then
      nNewForeColor = pForeColor
    Else
      nNewForeColor = NewForeColor
      If SetNewForeColor Then
        pForeColor = NewForeColor
      End If
    End If
    If nOldForeColor = nNewForeColor Then
      Err.Raise tfcErrSameColors, "TvwForeColors.ReplaceForeColor"
    Else
      With pTreeView
        LockWindowUpdate .hwnd
        If pValidateByNode Then
          For Each nNode In .Nodes
            nNoChange = False
            With nNode
              If .ForeColor = nOldForeColor Then
                RaiseEvent _
                 ValidateNode(nNode, nNewForeColor, nNoChange)
                If Not nNoChange Then
                  .ForeColor = nNewForeColor
                End If
              End If
            End With
          Next
        Else
          For Each nNode In .Nodes
            With nNode
              If .ForeColor = nOldForeColor Then
                .ForeColor = nNewForeColor
              End If
            End With
          Next
        End If
        LockWindowUpdate 0&
      End With
    End If
  End If
End Sub

Da diese letzte Prozedur auch sonst für ein TreeView-Steuerelement der Version 6 ganz praktisch sein kann, ist sie auch noch einmal als eigenständige Variante unter dem Namen TreeViewReplaceForeColor im Modul modTvwSetForeColor enthalten. Sie unterscheidet sich dadurch von der Methode der Klasse, dass es dort zum einen keine voreingestellte allgemeine Textfarbe gibt, und zum anderen das Validierungs-Ereignis für jeden Knoten entfällt:

Public Sub TreeViewReplaceForeColor(TreeView As TreeView, _
 ByVal OldForeColor As Variant, _
 ByVal NewForeColor As Variant)

  Dim nNode As Node
  
  If OldForeColor = NewForeColor Then
    Exit Sub
  Else
    With TreeView
      LockWindowUpdate .hwnd
      For Each nNode In .Nodes
        With nNode
          If .ForeColor = OldForeColor Then
            .ForeColor = NewForeColor
          End If
        End With
      Next
      LockWindowUpdate 0&
    End With
  End If
End Sub

Modul modTvwSetForeColor und Klasse TvwForeColors (tvwforecolor.zip - ca. 2,4 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche



Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer