欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

ScintillaNET的应用

2. 括号的匹配和高亮

为了方便多处调用该控件,继承scintilla类,实现“自定义”控件,以下均以这种做法来实现功能。

重写onupdateui事件,在updateui中实现括号匹配功能。

ScintillaNET的应用
 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 }
view code

3. ctrl+z会一次性清空所有的修改

ScintillaNET的应用
 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 }
view code

4.缩进调整

ScintillaNET的应用
 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 }
view code

目前整理了这么多,有机会再继续深入理解和应用scintillanet。