出于工作需要,需要制作一个嵌入在桌面应用中的C语言编辑器,经过一系列调研,目前ScintillaNET应该是最合适的了,开源、轻便、功能丰富,但是踩得坑也很多,接下面一一说道。
目前ScintillaNET托管在https://github.com/jacobslusser/ScintillaNET,拉下来重新编译。由于需要移植到.NET 2.0的平台上,需要修改源码中的对Linq的依赖,这里不多说,把目标框架改为.NET 2.0,编译,哪里报错改哪里。
1. 编辑器风格
参考:https://github.com/robinrodricks/ScintillaNET.Demo
2. 括号的匹配和高亮
为了方便多处调用该控件,继承Scintilla类,实现“自定义”控件,以下均以这种做法来实现功能。
重写OnUpdateUI事件,在UpdateUI中实现括号匹配功能。

1 private int m_lastCaretPos =0; 2 protected override void OnUpdateUI(UpdateUIEventArgs e) 3 { 4 base.OnUpdateUI(e); 5 MatchAndLightBracket(); 6 } 7 private void MatchAndLightBracket() 8 { 9 // Has the caret changed position?10 int caretPos = this.CurrentPosition;11 if (m_lastCaretPos != caretPos)12 {13 m_lastCaretPos = caretPos;14 int bracePos1 = -1;15 int bracePos2 = -1;16 17 // Is there a brace to the left or right?18 if (caretPos > 0 && IsBrace(this.GetCharAt(caretPos - 1)))19 bracePos1 = (caretPos - 1);20 else if (IsBrace(this.GetCharAt(caretPos)))21 bracePos1 = caretPos;22 23 if (bracePos1 >= 0)24 {25 // Find the matching brace26 bracePos2 = this.BraceMatch(bracePos1);27 if (bracePos2 == CodeEditor.InvalidPosition)28 {29 ReleaseHighlightB();30 }31 else32 {33 ReleaseHighlightB();34 HighlightBracket(bracePos1);35 HighlightBracket(bracePos2);36 }37 }38 else39 {40 ReleaseHighlightB();41 }42 }43 }44 private void HighlightBracket(int pos)45 {46 if (pos < 0)47 return;48 this.IndicatorFillRange(pos, 1);49 }50 private void ReleaseHighlightB()51 {52 this.IndicatorClearRange(0, this.TextLength);53 }54 private static bool IsBrace(int c)55 {56 switch (c)57 {58 case '(':59 case ')':60 case '[':61 case ']':62 case '{':63 case '}':64 case '<':65 case '>':66 return true;67 }68 69 return false;70 }
3. Ctrl+Z会一次性清空所有的修改

1 protected override void OnBeforeInsert(BeforeModificationEventArgs e) 2 { 3 base.OnBeforeInsert(e); 4 Count = this.Text.Length; 5 this.BeginUndoAction(); 6 } 7 protected override void OnInsert(ModificationEventArgs e) 8 { 9 base.OnInsert(e);10 if (Count < this.Text.Length)11 this.EndUndoAction(); 12 }
4.缩进调整

1 protected override void OnCharAdded(CharAddedEventArgs e) 2 { 3 base.OnCharAdded(e); 4 AutoIndicator(); 5 } 6 private void AutoIndicator() 7 { 8 int pos = this.CurrentPosition; 9 if (pos > 3 && this.GetCharAt(pos - 1) == ' ' && this.GetCharAt(pos - 2) == ' ')10 {11 if (this.GetCharAt(pos - 3) == '{')12 {13 string[] Text = GetStringList();14 string line = Text[this.CurrentLine - 1];15 int start = line.IndexOf(line.TrimStart());16 string ss = line.Substring(0, start);17 string str = new string(' ',4);18 this.InsertText(pos, ss+str);19 this.SelectionStart = this.SelectionEnd = pos + ss.Length + 4;20 }21 else22 {23 string[] Text = GetStringList();24 string line = Text[this.CurrentLine - 1];25 int start = line.IndexOf(line.TrimStart());26 string ss = line.Substring(0, start);27 this.InsertText(pos, ss);28 this.SelectionStart = this.SelectionEnd = pos + ss.Length;29 }30 31 }32 }33 private string[] GetStringList()34 {35 string[] s = new string[] { " " };36 return this.Text.Split(s, StringSplitOptions.None);37 }
目前整理了这么多,有机会再继续深入理解和应用ScintillaNET。
---------------------
作者:EditCode
来源:CNBLOGS
原文:https://www.cnblogs.com/hawk007/p/10383528.html
版权声明:本文为作者原创文章,转载请附上博文链接!