用 C# 编写的语法高亮文本框






4.78/5 (77投票s)
2005年5月30日
3分钟阅读

1003601

12453
本文介绍了 RichTextBox 的代码,该代码知道如何高亮文本部分并提供自动完成功能。
引言
嘿。 这段代码是一个派生自 .Net 的 RichTextBox
的类。 它提供语法高亮和自动完成功能(就像 Intellisense,只是稍微笨一点)。
背景
你是否曾经编写过具有自己脚本语言的应用程序? 是否需要在您的应用程序中编辑 SQL/代码? 您是否只是想要一个比具有固定宽度字体的 TextBox
更好的控件? 现在你可以拥有它了:-)
当我需要在自己编写的应用程序中编辑 SQL 时,编写了这个控件。 然后我想
“即使我能找到一个可以很好地编辑 SQL 的控件,它仍然不会高亮我编写的表名或存储过程名。而且我知道我需要一个可以高亮我自己脚本语言的控件……”
所以我坐下来写了它。 后来我意识到没有自动完成的语法高亮意义不大,所以我添加了对自动完成的支持。
使用代码
首先,我必须道歉。 我不太擅长 GUI 编程,所以我所有的操作都是使用代码完成的,因为我缺乏为 PropertyGrid
编写自定义编辑器的知识。 解决了这个问题,我们可以继续! 该控件有两个用于高亮的输入
- 分隔符: 使用
Seperators
属性访问。每个分隔符都是一个
char
,并且后面被称为“token”的是分隔符之间的非空字符串。 - 高亮描述符: 你可以使用(多么令人惊讶)
HighlightDescriptor
方法添加一个HighlightDescriptor
。HighlightDescriptor
是一个描述高亮规则的类的实例,它可以分为 token 识别信息和设计信息。
高亮规则
高亮规则有 6 个字段,使用它们构建
- Token: 稍后与文本进行比较的字符串。
- DescriptorType: 设置高亮类型。选项有:到单词的末尾、到行的末尾,以及到相应的结束 token。
- DescriptorRecognition: 确定 token 如何与文本中的 token 进行比较。选项有:文本等于 token,文本以 token 开头,文本包含 token。
- Color: 设置高亮时 token 的颜色。
- Font: 设置高亮时 token 的字体。 这个字段是可选的。
- UseForAutoComplete: 确定 token 是否将用于自动完成。
由于懒惰,HighlightDescriptor
的值只能在构造函数中设置。 <SideNote> 我真的认为 readonly
关键字被低估了。</SideNote>。
HighlightDescriptor
如下
public class HighlightDescriptor
{
public HighlightDescriptor(string token,
string closeToken, Color color, Font font,
DescriptorType descriptorType, DescriptorRecognition dr,
bool useForAutoComplete)
{
Color = color;
Font = font;
Token = token;
DescriptorType = descriptorType;
CloseToken = closeToken;
DescriptorRecognition = dr;
UseForAutoComplete = useForAutoComplete;
}
public readonly Color Color;
public readonly Font Font;
public readonly string Token;
public readonly string CloseToken;
public readonly DescriptorType DescriptorType;
public readonly DescriptorRecognition DescriptorRecognition;
public readonly bool UseForAutoComplete;
}
关注点
写作过程中发生了一些有趣的事情
- 滚动条:由于每次文本更改时,我实际上都会再次更改它(就基础文本框而言),因此滚动条会将自身重置为最顶部和最左边的位置。 为了解决这个问题,我使用了
EM_GETSCROLLPOS
和EM_GETSCROLLPOS
Windows 消息#region Scrollbar positions functions /// <summary> /// Sends a win32 message to get the scrollbars' position. /// </summary> /// <returns>a POINT structre containing horizontal /// and vertical scrollbar position.</returns> private unsafe Win32.POINT GetScrollPos() { Win32.POINT res = new Win32.POINT(); IntPtr ptr = new IntPtr(&res); Win32.SendMessage(Handle, Win32.EM_GETSCROLLPOS, 0, ptr); return res; } /// <summary> /// Sends a win32 message to set scrollbars position. /// </summary> /// <param name="point">a POINT /// conatining H/Vscrollbar scrollpos.</param> private unsafe void SetScrollPos(Win32.POINT point) { IntPtr ptr = new IntPtr(&point); Win32.SendMessage(Handle, Win32.EM_SETSCROLLPOS, 0, ptr); } #endregion
- 键盘笔画:在自动完成功能的工作期间,我发现即使您覆盖了
OnKeyDown
方法并且不调用基本方法,仍然会处理包含实际字符的键的按键(它们使用WM_CHAR
消息到达)。 因此,我决定覆盖WndProc
方法并在该级别过滤掉不需要的按键。 - RTF:我并没有真正为这个项目学习 RTF。 我只是采用了一个常规的
RichTextBox
,并了解了我需要构建什么来满足我的需求。 因此,我生成的 RTF 可能不是最佳的。 它可能具有可以通过操作 RTF 标头轻松解决的语言限制。
历史
- 2005/05/29:首次发布。
- 2005/06/04:修复了一些使用
ToCloseToken
DescriptorType 时的错误。 - 2005/07/13:修复了一些错误,添加了撤消/重做功能。