Click here to Skip to main content
Click here to Skip to main content

Real Time SynTax Colorizing

, 25 Apr 2004
Rate this:
Please Sign up or sign in to vote.
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:

    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ' 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.

    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ' 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

Share

About the Author


Comments and Discussions

 
GeneralMy vote of 2 PinmvpDave Kreskowiak29-Jul-09 4:47 
GeneralMake a class! Pinmemberzauberfee13-Oct-08 5:27 
QuestionBackground highlight line if it starts with "fox" PinmemberUltraWhack16-Jun-08 5:45 
GeneralWeird problems PinmemberThe Mighty Atom14-Jan-08 4:10 
GeneralRe: Weird problems PinmemberThe Mighty Atom19-Jan-08 9:36 
GeneralNice code PinmemberIDstrife15-Oct-06 6:07 
GeneralFirstVisibleLine() PinmemberSilberztein28-Oct-05 2:53 
GeneralExtremely Poor Performance PinmemberandrewPP21-Mar-05 20:30 
GeneralMake it a module Pinmembernanbil24-Sep-04 6:04 
GeneralRe: Make it a module PinmemberAaron Eldreth6-Oct-04 3:24 
GeneralInteresting... a little bug though PinmemberRyan Binns14-Sep-04 19:13 
GeneralRe: Interesting... a little bug though PinmemberAaron Eldreth15-Sep-04 11:51 
GeneralRe: Interesting... a little bug though Pinmembernanbil24-Sep-04 6:12 
GeneralSuggestions for a successful colorizer Pinmembercaractacus29-Apr-04 2:45 
GeneralRe: Suggestions for a successful colorizer PinmemberAaron Eldreth29-Apr-04 10:39 
GeneralThis sounds interesting; any references? PinmemberRolf Schaeuble5-May-04 1:28 
GeneralRe: This sounds interesting; any references? Pinmembercaractacus5-May-04 4:14 
GeneralRe: This sounds interesting; any references? PinmemberRolf Schaeuble5-May-04 11:07 
GeneralFiles Problem PinmemberDejan Petrovic27-Apr-04 15:20 
GeneralRe: Files Problem PinmemberAaron Eldreth27-Apr-04 17:07 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 26 Apr 2004
Article Copyright 2004 by Aaron Eldreth
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid