Last Updated: 7 Jun, 2012
Initiated: 3 Jun, 2012
Supports Rapid coloring of textbox with syntax highlighting and code folding
[Ukraine] translated by Pavel torgashov
Custom text editor with syntax highlighted.
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012
Byoy's comment: syntax highlighting is a feature that almost all ides need. This feature is often used when developing software in some industries. Torgashov took about one year to complete the fastcoloredtextbox control with rich functions and gorgeous effects. Compared with the popular icsharpcode. texteditor in the early days, it was very powerful. Is a rare open-source syntax highlighting control in recent years. Some programming ideas (such as delayed event processing and style masks) in this article are of great guiding significance for us to learn and improve our programming skills and design thinking. This control is extremely powerful, so this article is very long! The translation time is not fixed. Please add it to favorites or RSS.
Click to read the original article
Download source code-2.1 MB
Download the demo-159 KB
Download the source code for. NET Compact Framework 2.0 and demo-301.86 KB
Download help (CHM)-1.7 MB
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012
Introduction
When I was working on a project, I encountered a text editor that needed to support syntax highlighting. At first, I used a component inherited from RichTextBox. However, when I use it to process a large amount of text, I find that Using RichTextBox to color a large number of text fragments (200 or more) is very slow. When this coloring method must be used for dynamic processing, it will cause serious problems.
So I created my own text component-neither windows textbox nor RichTextBox.
Text rendering is completed completely by using the pure GDI + method.
This component can process a large amount of text quickly enough and contains various tools, allowing me to easily complete dynamic syntax highlighting.
It can set the foreground color, font style, and background color of the selected text symbol. You can use regular expressions to easily access text content. Similarly, this component supports automatic line feed, search/replacement, code folding, and multi-step Undo/redo ).
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012
Implementation
To save each character in the text, I use the char struct:
public struct Char{ public char c; public StyleIndex style;}
This struct stores the symbols (char, 2 bytes) and style index masks (styleindex, 2 bytes ). Therefore, each character in the text consumes 4 bytes of memory. Use List <char> to group symbols by row.
Styleindex is the style index mask used for character. Each bit of styleindex corresponds to the style of the drawing symbol. Because styleindex only has 16 bits (2 bytes), the control only supports different styleindexes within 16 types.
Styles are stored in a separate list:
public readonly Style[] Styles = new Style[sizeof(ushort)*8];
In fact, style is the Renderer for characters, backgrounds, borders, and other text design elements.
The following is a typical Implementation of rendering text characters using styles:
Public class textstyle: style {public brush forebrush {Get; set;} public brush backgroundbrush {Get; set;} public fontstyle {Get; set ;} public override void draw (Graphics GR, point position, Range) {// draw the background if (backgroundbrush! = NULL) gr. fillrectangle (backgroundbrush, position. x, position. y, (range. end. ichar-range. start. ichar) * range. TB. charwidth, range. TB. charheight); // draw the Character Font F = new font (range. TB. font, fontstyle); line = range. TB [range. start. iline]; float dx = range. TB. charwidth; float y = position. y-2f; float x = position. x-2f; brush forebrush = This. forebrush ?? New solidbrush (range. TB. forecolor); For (INT I = range. start. ichar; I <range. end. ichar; I ++) {// draw a single character gr. drawstring (line [I]. c. tostring (), F, forebrush, x, y); x + = DX ;}}}
Textstyle contains the text foreground color, background color, and font style. When creating a new style, the component checks its style table. If the style does not exist, it creates a new style with its index.
You can create custom styles from the style class.
The range class represents a continuous text block. It uses the given initial and end positions to process text fragments:
public class Range{ Place start; Place end;}public struct Place{ int iLine; int iChar;}
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012
Source code
Syntax highlighting
Unlike RichTextBox, our component is not syntactically highlighted using RTF. The component saves the color and style information of each symbol, which means that the color is re-colored every time the text is input. So there is the textchanged event.
By passing a range object as a parameter to the textchanged event, you can allow the component to highlight and color only the changed part of the text each time.
After specifying the search mode (Regular Expression), you can use the overloaded range. setstyle () to find the text fragment to be colored. For example, the following code can be used to search for comments in C # (a line of text starting ):
Style greenstyle = new textstyle (brushes. green, null, fontstyle. italic );... private void fastcoloredtextbox1_textchanged (Object sender, textchangedeventargs e) {// clear style e. changedrange. clearstyle (greenstyle); // highlight E. changedrange. setstyle (greenstyle ,@"//. * $ ", regexoptions. multiline );}
The above code first calls the range. clearstyle () method to clear the text style before coloring.
Although the setstyle () method can be used to color text fragments that match the given regular expression, if the regular expression contains a group named "range, all groups named "range" are colored. The following code demonstrates how to bold the words following the keywords "class", "struct", and "Enum:
e.ChangedRange.SetStyle(BoldStyle, @"\b(class|struct|enum)\s+(?<range>[\w_]+?)\b");
The example Program (DEMO) provided in this article implements textchanged Event code for C #, VB, HTML, and other language syntax highlighting.
In addition to the textchanged event, textchanging, visiblerangechanged, and selectionchanged events may also be used. The textchanging event occurs before the text changes. The selectionchanged event occurs after the cursor position or the selected text segment changes.
Code folding
My components allow you to hide text blocks by using the collapseblock () method:
fastColoredTextBox1.CollapseBlock(fastColoredTextBox1.Selection.Start.iLine, fastColoredTextBox1.Selection.End.iLine);
Is a demonstration of this effect:
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012
My components also support automatic searching for collapsed fragments (collapsed areas ). You can set the range. setfoldingmarkers () mode (Regular Expression) in the textchanged event to find the start and end positions of the folding block.
For example, to search for the code block surrounded by "{...}" and "# region .. # endregion", set it as follows:
Private void fastcoloredtextbox1_textchanged (Object sender, textchangedeventargs e) {// clear the folding Mark E of the changed part. changedrange. clearfoldingmarkers (); // set the folding tag e. changedrange. setfoldingmarkers ("{", "}"); E. changedrange. setfoldingmarkers (@ "# region \ B", @ "# endregion \ B ");}
Is the effect demonstration:
Folding blocks can be nested with each other.
To expand the collapsed code block, you only need to double-click the code block or collapse it to mark "+ 」. Click on the collapsed code block to select the entire code block. You can also use the expandblock () method to expand hidden code blocks.
The demo contains a demo of folding all # region... # endregion in the text.
The folding block also allows you to visually define the boundary of the code block where the cursor is located. In this case, draw a vertical line (fold indicator, vertical green line within the arrow range-byoy note) on the left of the component to indicate the collapsed area of the cursor.
Latency Processing
Many events (textchanged, selectionchanged, and visiblerangechanged) have their corresponding delayed processing versions. A delayed event is triggered at a certain time point after an important event occurs.
What does this mean? For example, if you enter text quickly, the textchanged event is triggered when you enter each character, while textchangeddelayed is triggered only once after you stop the input.
This is very useful for the delay coloring of a large number of texts.
My components support the following latency events: textchangeddelayed, selectionchangeddelayed, and visiblerangechangeddelayed. The delayedeventsinterval and delayedtextchangedinterval attributes contain the time needed for latency.
Export to HTML
This component has an HTML attribute that returns the HTML code of the colored text. You can also use the exporttohtml class to export HTML to print or paste it to a website.
Clipboard
This component can copy text in two formats: plain text and HTML.
If the target program supports inserting HTML (such as Microsoft Word), the colored text will be pasted. In other cases (such as NotePad), plain text is pasted.
Shortcut Key
This control supports the following shortcut keys:
- Left, right, top, bottom, home, end, Pageup, Pagedown-move the cursor
- Shift + (left, right, top, bottom, home, end, Pageup, Pagedown)-move cursor with selection area
- CTRL + F, CTRL + H-displayed search and replace dialog box
- F3-find the next
- CTRL + G-displayed "go to" dialog box
- CTRL + (C, V, x)-standard clipboard operations
- CTRL + A-select all text
- CTRL + Z, ALT + return key, CTRL + R-Undo/Redo
- Tab, Shift + TAB-increase/decrease indentation
- CTRL + home, CTRL + end-to the beginning/end of the text
- Shift + Ctrl + home, Shift + Ctrl + right-move a word to the left/right
- CTRL +-, Shift + Ctrl +--Move backward/forward
- CTRL + u, Shift + Ctrl + U-convert the selected text into uppercase/lowercase letters
- CTRL + Shift + C-Comment/cancel comment
- INS-insert/replace
- CTRL + return key, CTRL + Del-delete words on the left/right
- Alt + mouse, ALT + Shift + (top, bottom, left, right)-column selection mode
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012
Bracket highlighted
(To be continued)
Written by Pavel torgashov 2011, translated by byoy "conmajia" 2012