ScintillaNET的应用
程序员文章站
2022-10-01 11:32:53
出于工作需要,需要制作一个嵌入在桌面应用中的C语言编辑器,经过一系列调研,目前ScintillaNET应该是最合适的了,开源、轻便、功能丰富,但是踩得坑也很多,接下面一一说道。 目前ScintillaNET托管在https://github.com/jacobslusser/ScintillaNET ......
出于工作需要,需要制作一个嵌入在桌面应用中的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 brace 26 bracepos2 = this.bracematch(bracepos1); 27 if (bracepos2 == codeeditor.invalidposition) 28 { 29 releasehighlightb(); 30 } 31 else 32 { 33 releasehighlightb(); 34 highlightbracket(bracepos1); 35 highlightbracket(bracepos2); 36 } 37 } 38 else 39 { 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) == '\n' && this.getcharat(pos - 2) == '\r') 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 else 22 { 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[] { "\n" }; 36 return this.text.split(s, stringsplitoptions.none); 37 }
目前整理了这么多,有机会再继续深入理解和应用scintillanet。
上一篇: 为什么产业互联网是工业转型的必然之路
下一篇: 直播农业和众筹农业给农村电商带来机会