【TIPS】VB.NetのRichTextBoxでSyntax Highlightしたい

> **Note:** 本記事は、2018年11月時点の内容です。

# 【Q】VB.NetのRichTextBoxで自前でSyntax Highlightしたいがどうやったらよい？

* そんなん自作しないでコンポーネント使おうぜという方は、↓こちらをおすすめします。
    * `FCTB` は無償。`ALTERNET：CODE EDITOR` は有償。

> **nuget : FCTB** 

> * https://www.nuget.org/packages/FCTB/

> **ALTERNET：CODE EDITOR** 

> * https://www.alternetsoft.com/products/editor

* .Netではなく、Javascriptならいい感じのライブラリがあるので困ることはなさそう。
    * `Monaco Editor` はMicrosoft。`code prettifier`はGoogle。

> **GitHub : Monaco Editor** 

> * https://github.com/Microsoft/monaco-editor

> **GitHub : code prettifier** 

> * https://github.com/google/code-prettify



# 【A】↓こんな感じでできた。

* 参考資料は、以下の通り。

> **[GUIDE] Syntax Highlighting in RichTextBox** 

> * http://www.vbforums.com/showthread.php?776231-GUIDE-Syntax-Highlighting-in-RichTextBox

* コピペでいけると思いきや、ちょっとバグってる（気がする。Syntax Highlight後のカーソル位置）。あと、めっちゃ画面がチラチラする。


* 画面のチラツキはダブルバッファリングを試したが解消せず。Windows APIを使って描画を停止することで解消。

> **Is there BeginUpdate, EndUpdate with the RichTextBox control?** 

> * https://www.experts-exchange.com/questions/21570407/Is-there-BeginUpdate-EndUpdate-with-the-RichTextBox-control.html


## 作業の手順
1. WinFormsアプリの作成
2. コーディング

### 【手順1】WinFormsアプリの作成
* Visual Studioで空のWinFormsアプリを作成する

### 【手順2】コーディング
* デザイナで、FormにRichTextBox(`RichTextBox1` とする)を貼り付け
* コードエディタで以下コードを貼り付け
    * TextChangedイベントにSyntax Highlightロジックを実装する


```vb:Form1.vb
Imports System.Text.RegularExpressions

Public Class Form1
    ' Windows API (ウインドウ描画停止)
    Private Declare Function LockWindowUpdate Lib "user32" Alias "LockWindowUpdate" (ByVal hWnd As IntPtr) As Integer

    Private Sub RichTextBox1_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox1.TextChanged

        Dim tokens As String = "(regex|dim|object|new|string|public|integer|end|auto|double|int|struct|break|else|long|switch|case|enum|register|typedef|char|extern|return|union|const|float|short|unsigned|continue|for|signed|void|default|goto|sizeof|volatile|do|if|static|while|1|2|3|4|5|6|7|8|9|my)"
        Dim rex As New Regex(tokens)
        Dim mc As MatchCollection = rex.Matches(RichTextBox1.Text)
        Dim StartCursorPosition As Integer = RichTextBox1.SelectionStart

        ' 描画を一時停止
        LockWindowUpdate(RichTextBox1.Handle)

        ' Syntax Highlight
        For Each m As Match In mc
            Dim startIndex As Integer = m.Index
            Dim StopIndex As Integer = m.Length
            RichTextBox1.[Select](startIndex, StopIndex)
            RichTextBox1.SelectionColor = Color.Blue
            RichTextBox1.Select(StartCursorPosition, 0)
            RichTextBox1.SelectionColor = Color.Black
        Next

        ' 描画を再開
        LockWindowUpdate(IntPtr.Zero)
    End Sub
End Class
```

> **Note:** 
> `token`にSyntax Highlightしたいキーワードをセットする

## 関連情報
* 今回は使えなかったが、画面描画系の情報をメモ。

> **コントロールのダブルバッファリングを有効にして、ちらつきを防止する** 

> * https://dobon.net/vb/dotnet/control/doublebuffered.html

> **コントロールの描画を一時的に停止する** 

> * https://dobon.net/vb/dotnet/control/beginupdate.html

> **Vb.NET ListView DoubleBuffered（ダブルバッファ）** 

> * https://plaza.rakuten.co.jp/cocoab/diary/201706130001/

> **C# エディタのシンタックスハイライター処理を速くする方法** 

> * https://hibara.org/blog/2013/06/20/syntax-hightlighter/

> **[Tips][RichTextBox] Undo/Redoを実行する** 

> * http://blog.hiros-dot.net/?p=1500