Click here to Skip to main content
15,868,128 members
Articles / Programming Languages / Visual Basic
Article

Real Time SynTax Colorizing

Rate me:
Please Sign up or sign in to vote.
3.22/5 (21 votes)
25 Apr 20042 min read 94.5K   629   39   22
Aaron shows how to use the RichTextbox for Real Time Syntax Coloring painlessly.

Sample Image - syntaxcolorizing.jpg

Introduction

There seems to be three ways to do real time syntax coloring. Good, fast, and flicker-free. Pick any two. Matthew Hazlett did an article that covers "good and flicker-free", so I thought some people might find it useful to have simply "good and fast".

Background

Back in January, I worked on HTML syntax coloring. I was amazed by the lack of information on the subject in VB.NET. There was some in VB, but naturally, it didn't upgrade too well (nothing is ever easy). So, I had to make my own. Isn't that how things typically are? I've learned a lot from CodeProject, and would like to give back.

Using the code

The code is pretty much self-explanatory, but the idea behind it works something like this:

  1. Find the number of visible lines.
  2. For each visible line, color it.

Simple enough, eh?

Now, on to the actual code, the first subroutine that finds the number of visible lines is called ColorVisibleLines and it looks something like this:

VB
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' Sub: ColorVisibleLines()
' It does what?: Colors the visible lines in the RichTextbox
' Notes: N/A
Public Sub ColorVisibleLines(ByVal rtb As RichTextBox)
    Dim FirstLine As Integer = FirstVisibleLine()
    Dim LastLine As Integer = LastVisibleLine()
    Dim FirstVisibleChar As Integer
    Dim i As Integer = FirstLine

    If (FirstLine = 0) And (LastLine = 0) Then
        ' If there is no text in the control, it will run an error
        ' So, if there isn't any text, just exit
        Exit Sub
    Else
        While i < LastLine

            FirstVisibleChar = GetCharFromLineIndex(FirstLine)

            ColorLineNumber(rtb, FirstLine, FirstVisibleChar)

            FirstLine += 1
            i += 1
        End While
    End If
End Sub

As you will notice, this sub calls another sub to do all the actual coloring for us.

VB
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' Sub: ColorLineNumber()
' It does what?: Colors a single line in the control
' Notes: This should be fairly simple, it looks to see
'  if there are any comments, colors them. Then, it loops
'  through the keywords defined, and colors them
Public Sub ColorLineNumber(ByVal rtb As RichTextBox, _
        ByVal LineIndex As Integer, ByVal lStart As Integer)
    Dim Line As String = rtb.Lines(LineIndex).ToLower
    Dim i As Integer = 0
    Dim Instance As Integer
    Dim SelectionAt As Integer = rtb.SelectionStart

    ' Lock the update
    LockWindowUpdate(rtb.Handle.ToInt32)

    ' Color the line black to remove any previous coloring
    rtb.SelectionStart = lStart
    rtb.SelectionLength = Line.Length
    rtb.SelectionColor = Color.Black

    ' Find any comments
    Instance = InStr(Line, "'")

    ' If there are comments, color them
    If Instance <> 0 Then
        rtb.SelectionStart = (lStart + Instance - 1)
        rtb.SelectionLength = (Line.Length - Instance + 1)
        rtb.SelectionColor = Color.Green
    End If

    ' There was a comment, so to aviod coloring over the comment
    '  we exit. Unfortunately, this can present a problem 'cuz
    '  what if the user comments at the end of a line with code on it.
    If Instance = 1 Then
        ' Unlock the update, restore the start and exit
        rtb.SelectionStart = SelectionAt
        rtb.SelectionLength = 0
        LockWindowUpdate(0)
        Exit Sub
    End If

    ' Loop through all the Keywords
    While i < Words.Length

        ' See if the word is in the Line
        Instance = InStr(Line, Words(i).Word)

        ' If the lines contains the word, color it
        If Instance <> 0 Then
            rtb.SelectionStart = (lStart + Instance - 1)
            rtb.SelectionLength = Words(i).Word.Length
            rtb.SelectionColor = Words(i).Color
        End If

        i += 1
    End While

    ' Restore the selectionstart
    rtb.SelectionStart = SelectionAt
    rtb.SelectionLength = 0

    ' Unlock the update
    LockWindowUpdate(0)
End Sub

The keywords to be colored are stored in a structure called KeyWords which holds the string to color, and the color to color the string.

Closing

All in all, it's not the most efficient way to color things. For example, you may have noticed that the Instr function is used to locate the keywords. Regular Expressions (or RegEx) could be used in lieu of the method currently implemented.

Another downside to this method is flicker. This is a very difficult issue to overcome. Even with the LockWindowUpdate API function, it still flickers (go figure). I am currently attempting to make a non-inherited RichTextBox that will be a clone of Visual Studio's editor. However, it's still a long distance from completion. The control will be free and I'll post it on CodeProject, and it will contain a lot of features such as line numbering, breakpoints, brace-matching, expanding-collapsing regions, and best of all good, fast, and flicker-free real time syntax coloring.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here



Comments and Discussions

 
QuestionHelp | if have 2 syntax not highlight Pin
Eki Indradi24-Dec-15 19:09
Eki Indradi24-Dec-15 19:09 
QuestionTHANKS !!! Pin
Eki Indradi22-Dec-15 0:14
Eki Indradi22-Dec-15 0:14 
GeneralMy vote of 2 Pin
Dave Kreskowiak29-Jul-09 3:47
mveDave Kreskowiak29-Jul-09 3:47 
GeneralMake a class! Pin
zauberfee13-Oct-08 4:27
zauberfee13-Oct-08 4:27 
QuestionBackground highlight line if it starts with "fox" Pin
UltraWhack16-Jun-08 4:45
UltraWhack16-Jun-08 4:45 
GeneralWeird problems Pin
The Mighty Atom14-Jan-08 3:10
The Mighty Atom14-Jan-08 3:10 
GeneralRe: Weird problems Pin
The Mighty Atom19-Jan-08 8:36
The Mighty Atom19-Jan-08 8:36 
GeneralNice code Pin
IDstrife15-Oct-06 5:07
IDstrife15-Oct-06 5:07 
GeneralFirstVisibleLine() Pin
Silberztein28-Oct-05 1:53
Silberztein28-Oct-05 1:53 
GeneralExtremely Poor Performance Pin
andrew|21-Mar-05 19:30
andrew|21-Mar-05 19:30 
GeneralMake it a module Pin
nanbil24-Sep-04 5:04
nanbil24-Sep-04 5:04 
GeneralRe: Make it a module Pin
Aaron Eldreth6-Oct-04 2:24
Aaron Eldreth6-Oct-04 2:24 
GeneralInteresting... a little bug though Pin
Ryan Binns14-Sep-04 18:13
Ryan Binns14-Sep-04 18:13 
GeneralRe: Interesting... a little bug though Pin
Aaron Eldreth15-Sep-04 10:51
Aaron Eldreth15-Sep-04 10:51 
GeneralRe: Interesting... a little bug though Pin
nanbil24-Sep-04 5:12
nanbil24-Sep-04 5:12 
GeneralSuggestions for a successful colorizer Pin
caractacus29-Apr-04 1:45
caractacus29-Apr-04 1:45 
GeneralRe: Suggestions for a successful colorizer Pin
Aaron Eldreth29-Apr-04 9:39
Aaron Eldreth29-Apr-04 9:39 
GeneralThis sounds interesting; any references? Pin
Rolf Schaeuble5-May-04 0:28
Rolf Schaeuble5-May-04 0:28 
GeneralRe: This sounds interesting; any references? Pin
caractacus5-May-04 3:14
caractacus5-May-04 3:14 
GeneralRe: This sounds interesting; any references? Pin
Rolf Schaeuble5-May-04 10:07
Rolf Schaeuble5-May-04 10:07 
GeneralFiles Problem Pin
Dejan Petrovic27-Apr-04 14:20
Dejan Petrovic27-Apr-04 14:20 
GeneralRe: Files Problem Pin
Aaron Eldreth27-Apr-04 16:07
Aaron Eldreth27-Apr-04 16:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.