VB.NET: RegEx Syntax Highlighting RichTextBox
Here is a version of my code for syntax highlighting in a RichTextBox that incorporates regular expressions.
Download RegEx Syntax Highlighting RichTextBox Source Code
Source Code
Public Class SyntaxRTB
Inherits System.Windows.Forms.RichTextBox
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hWnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, _
ByVal lParam As Integer) As Integer
Private Declare Function LockWindowUpdate Lib "user32" _
(ByVal hWnd As Integer) As Integer
Private _SyntaxHighlight_CaseSensitive As Boolean = False
Friend Words As New DataTable
'Contains Windows Messages for the SendMessage API call
Private Enum EditMessages
LineIndex = 187
LineFromChar = 201
GetFirstVisibleLine = 206
CharFromPos = 215
PosFromChar = 1062
End Enum
Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)MyBase.OnTextChanged(e)
ColorVisibleLines()
End Sub
Public Sub New()
Me.AcceptsTab = True
AddSQLSyntax()
End Sub
Function AddSQLSyntax()
ClearSyntaxWords()
AddSyntaxWord("\b(select|text|ntext|date|datetime|order by|" & _
"group by|smalldatetime|cursor|on|as|for|filename|" & _
"database|drop|function|delete|insert|update|int|" & _
"varchar|nvarchar|bit|binary|table|inner|where|from|" & _
"out|procedure|view|trigger|set)\b", Color.Blue)
AddSyntaxWord("\b@@identity\b", Color.Pink)AddSyntaxWord(
"\b(in|join|outer|and|or)\b", Color.Gray) AddSyntaxWord("\bsp_refreshview\b", Color.Red)
Return True
End Function
Public Function ClearSyntaxWords() Words = New DataTable
''Load all the keywords and the colors to make them
Words.Columns.Add("Word")
Words.PrimaryKey = New DataColumn() {Words.Columns(0)}Words.Columns.Add(
"Color")
Return True
End Function
Public Function AddSyntaxWord(ByVal strWord As String, ByVal clrColor As Color)Dim MyRow As DataRow
MyRow = Words.NewRow()
MyRow("Word") = strWordMyRow(
"Color") = clrColor.Name
Words.Rows.Add(MyRow)
Return True
End Function
Public Sub ColorRtb()
Dim FirstVisibleChar As Integer
Dim i As Integer = 0While i < Me.Lines.Length
FirstVisibleChar = GetCharFromLineIndex(i)
ColorLineNumber(i, FirstVisibleChar)
i += 1
End While
End Sub
Public Sub ColorVisibleLines()
Dim FirstLine As Integer = FirstVisibleLine()
Dim LastLine As Integer = LastVisibleLine()
Dim FirstVisibleChar As Integer
If (FirstLine = 0) And (LastLine = 0) Then
'If there is no text it will error, so exit the sub
Exit Sub
Else
While FirstLine < LastLine
FirstVisibleChar = GetCharFromLineIndex(FirstLine)
ColorLineNumber(FirstLine, FirstVisibleChar)
FirstLine += 1
End While
End If
End Sub
Public Sub ColorLineNumber(ByVal LineIndex As Integer, ByVal lStart As Integer)
Dim i As Integer = 0
Dim SelectionAt As Integer = Me.SelectionStart Dim MyRow As DataRow
Dim MyI As Integer
' Lock the update
LockWindowUpdate(Me.Handle.ToInt32)
MyI = lStart
''Turn the whole link black before applying RegEx Syntax matching.
Me.SelectionStart = MyI
Me.SelectionLength = Lines(LineIndex).Length
Me.SelectionColor = Color.Black
''Check for matches in a particular line number
Dim rm As System.Text.RegularExpressions.MatchCollection
Dim m As System.Text.RegularExpressions.Match
For Each MyRow In Words.Rows
'"( |^)1.*2( |$)"
rm = System.Text.RegularExpressions.Regex.Matches(Me.Text, MyRow("Word"))
For Each m In rm
Me.SelectionStart = m.Index
Me.SelectionLength = m.Length
Me.SelectionColor = Color.FromName(MyRow("color"))
Next
Next
' Restore the selectionstart
Me.SelectionStart = SelectionAt
Me.SelectionLength = 0
Me.SelectionColor = Color.Black
' Unlock the update
LockWindowUpdate(0)
End Sub
Public Function GetCharFromLineIndex(ByVal LineIndex As Integer) As Integer
Return SendMessage(Me.Handle, EditMessages.LineIndex, LineIndex, 0)
End Function
Public Function FirstVisibleLine() As Integer
Return SendMessage(Me.Handle, EditMessages.GetFirstVisibleLine, 0, 0)
End Function
Public Function LastVisibleLine() As Integer
Dim LastLine As Integer = FirstVisibleLine() + (Me.Height / Me.Font.Height)
If LastLine > Me.Lines.Length Or LastLine = 0 Then
LastLine = Me.Lines.Length
End If
Return LastLine
End Function
Public Property CaseSensitive() As Boolean
Get
Return _SyntaxHighlight_CaseSensitive
End Get
Set(ByVal Value As Boolean)
_SyntaxHighlight_CaseSensitive = Value
End Set
End Property
End Class