Die Community zu .NET und Classic VB.
Menü

Syntaxhighlighting - RTF

 von 

Übersicht 

In diesem Tutor soll beschrieben werden, wie das Einfärben eines Wortes in der Richtextbox abläuft. Diese Methode ähnelt dem vom Visual Basic oder Visual C++, und zeigt auch dasselbe Verfahren.

Mit freundlichen Grüßen
Manuel Wessing

Allgemeines  

Gedanklich gesehen ist es eine einfache Idee ein Wort aus dem Text zu nehmen und die Wörter zu prüfen, und daraufhin einzufärben. Stellt man sich aber vor, dass der Text aus weit über 2000 Wörter besteht und bei jedem Tastendruck der komplette Text überprüft wird, steht man schnell vor einem Performanceproblem.

Immer nur das letzte Wort zu prüfen ist auch keine besonders gute Idee, wenn der Benutzer einmal in ein bereits geschriebenes Wort etwas ändert, ist die neue Einfärbung nicht gegeben.

Die Methode die hier beschrieben ist, prüft nur das Wort wo sich der Cursor gerade befindet. Als erstes sollten Sie eine Form anlegen und die RichTextBox darauf platzieren. Bitte benennen Sie diese in RTF1 um. Legen Sie weiterhin eine Modul Datei an.

Das Modul  

Erst einmal sollten die Wörter definiert werden, die eine farbliche Kennzeichnung erhalten, die Erstellung einer Keywordlist ist dabei von Vorteil. Sie kann auch von einer Datei geladen werden.

Dies wird in das Modul eingetragen:

Public Type CONST_Keywords
    Color As Long
    Keyword As String
End Type

Public KeyWordlist(2) As CONST_Keywords
Public Source As String

Es werden später zwei Wörter eingegeben, die eine Einfärbung erhalten (KeyWordlist(2)). Die Farbe wird in Color gespeichert. Die Zeichenfolge Source enthält den Text des RTF Steuerelements als eine Kopie. Dies ist besonders bei MDI Anwendungen interessant.

Form_Load  

Folgenden Code bitte im Form_Load Ereignis eingeben:

KeyWordlist(1).Keyword = "Start"
KeyWordlist(1).Color = vbBlue
   
KeyWordlist(2).Keyword = "End"
KeyWordlist(2).Color = vbRed

Für jedes Wort kann eine bestimmte Farbe definiert werden. Es spielt später keine Rolle, ob der Benutzer das Wort klein oder groß schreibt; es wird immer nach dieser Vorgabe geändert. Der wichtige Programmteil steht im RTF1_KeyUp Ereignis der RichTextBox. Das Programm soll nur Zeichen anzeigen wenn die Taste bereits gedrückt wurde.

RTF_KeyUP - das Wichtigste!  

Als vorbereitung sollte im KeyUp Ereignis des RTF1 folgende Variablen definiert werden:

Dim BeginWort As Long
Dim EndWort As Long
Dim AltPos As Long
Dim Pos As String
Dim Wort As String
Dim Char As String * 1

Los geht's ...

Das RTF Steuerelement hätte durch das Überprüfen des aktuellen Wortes und durch die ständige Einfärbung keine Möglichkeit Textteile mit der Tastatur zu markieren. Die Markierung würde immer direkt aufgehoben, da das Programm eine eigene Markierung einsetzt und dadurch die Textfarbe ändert.

Als erstes muss also auf Steuerzeichen für den Cursor geachtet werden. Zum Beispiel Pfeiltasten oder Pfeiltasten in Verbindung mit der Shift Taste. Der Folgende Programmteil prüft vorab ob es sich um eine Steuertaste handelt.

If (KeyCode > 33 And KeyCode < 40) Or (KeyCode > 33 And _
    KeyCode < 40 And Shift = 1) Or KeyCode = 16 Then
    Exit Sub
End If

Mit diesem Programmteil werden die Pfeilstasten und die Pos1 und Ende Taste mit Shift als auch ohne überprüft. Es wird also keine Wortprüfung stattfinden. So kann der Benutzer den Text mit der Tastatur selber markieren.

Als nächstes sollte der Text in die zweite Variable kopiert werden:

Source = RTF1.Text

Wenn es sich um eine MDI Anwendung handelt, kann hier die Übergabe an eine Collection sehr hilfreich sein.

Die wichtigste Information ist die aktuelle Cursor Position im Text. Diese wird mit der Eigenschaft SelStart ermittelt. Und in eine Lokale Variable gespeichert. Da die Cursor-Position verändert wird, brauchen wir eine Kopie der Cursor-Position, um den Cursor später wieder dort hinzubringen:

AltPos = RTF1.SelStart
Pos = AltPos

Das Erkennen eines Wortes ist in der Regel sehr einfach. Als erstes sucht das Programm nach dem Beginn des Wortes. Dabei sucht das Programm nach einem Trennzeichen. Ein Satz wird in einer Sprache meist durch ein Leerzeichen ( Engl. Space ) getrennt. Dieses Zeichen wird gesucht. Neben bei gibt es in einer Zeichenfolge keine Zeilenumbrüche. Ein Zeilenende wird mit Chr(13) & Chr(10) abgeschlossen. Nach diesen Zeichen wird weiterhin gesucht. Hier können auch weitere Zeichen eingetragen werden, wie ( oder ). Geachtet werden muss auch auf das Antreffen des Anfangs der Zeichenfolge. Wenn der Cursor Position -1 erreicht, beginnt logischerweise das Wort bei Position 0. Im RTF beginnt das erste Zeichen bei 0.

Do
    If Pos > 0 Then
        Char = Mid(Source, Pos, 1)
    Else
        BeginWort = 1
        Exit Do
    End If
    If Char = " " Or Char = Chr(10) Or Char = Chr(13) Or Pos = -1 Then
        BeginWort = Pos + 1
        Exit Do
    End If
    Pos = Pos - 1
Loop Until Pos < 0

Im Gegenzug muss auch das Ende des Wortes gesucht werden. Hier wird auch wieder auf ein Leerzeichen oder auf ein Zeilenende gesucht. Natürlich muss auch darauf geachtet werden ob das Ende der Zeichenfolge erreicht wurde.

Do
    Pos = Pos + 1
    If Pos <= Len(Source) Then
        Char = Mid(Source, Pos, 1)
    Else
        EndWort = Len(Source) + 1
        Exit Do
    End If
    If Char = " " Or Char = Chr(10) Or Char = Chr(13) Or _ 
        Pos > Len(Source) Then
        EndWort = Pos
        Exit Do
    End If
Loop Until Pos < 0

In den Variablen BeginWort und EndWort stehen nun die Start- und End-Positionen des Wortes unter dem Cursor.

Hier ist das Prinzip noch eimal erklärt.

Im ersten Schritt wird der Anfang des Wortes gesucht. (| = Cursor)

Hallo,dies ist ein S|atz

Der Cursor steht an Position 20. Das Programm wandert nun ein Zeichen zurück auf die 19, es erkennt dort kein Wortende und geht wieder einen Schritt zurück auf die 18. Dort wurde ein Leerzeichen gefunden. Somit muss also 19 der Anfang des Wortes sein. Das andere Verfahren ist ähnlich nur wird hier die Position immer um 1 erhöht.

Damit keine Überraschungen auftreten und sich der Cursor zwischen zwei Leerzeichen steht muss vorher eine Abfrage stattfinden:

If BeginWort > -1 And EndWort > -1 And (EndWort > BeginWort) Then

Nun kann es daran gehen, das Wort aus dem Text zu nehmen und es zu vergleichen:

Wort = Mid(Source, BeginWort, EndWort - BeginWort)

Nun ist das Wort bekannt, wo sich der Cursor befindet. Nun kann es auf Richtigkeit überprüft werden:

If Wort <> "" Then
    KeyWordColoring Wort, BeginWort
    RTF1.SelStart = AltPos
    RTF1.SelLength = 0
    RTF1.SelColor = vbBlack
End If

Es wird eine Sub Routine benutzt, um die Textstelle zu markieren und sie einzufärben. Der Cursor wird später wieder an die alte Textstelle gesetzt und die Farbe auf Schwarz geschaltet.

Hier der Quellcode der Routine KeyWordColoring:

Private Sub KeyWordColoring(Word As String, BeginWord As Long)
Dim Color As Long
    For t = 1 To UBound(KeyWordlist)
        If UCase(Word) = UCase(KeyWordlist(t).Keyword) Then
            Color = KeyWordlist(t).Color
            Found = t
            Exit For
        Else
            Color = vbBlack
            Found = 0
        End If
    Next 't
    RTF1.SelStart = BeginWord - 1
    RTF1.SelLength = Len(Word)
    RTF1.SelColor = Color
    If Found > 0 Then
        RTF1.SelText = KeyWordlist(t).Keyword
    End If
End Sub

Es werden alle Einträge der KeyWordList() abgearbeitet. Wurde das Wort in der Liste gefunden, wird die Position im RTF markiert und eingefärbt. Dazu wird noch die Schreibweise angepasst. Ist das Wort nicht in der Liste ( Found = 0 ) wird der Text Schwarz gezeichnet. Das Einfärben geschieht auch dann wenn das Wort bereits einmal eingefärbt wurde.

Download  

Hier können Sie ein Beispielprojekt downloaden.

Anmerkung: ActiveVB hat sich die Freiheit genommen, eine Liste der Visual-Basic-Schlüsselwörter in das Projektbeispiel einzubinden.

Beispielprojekt [3596 Bytes]

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.