Scintilla的高级技法

Waiting4you 发布于 2009/11/12 11:27
阅读 1K+
收藏 2

页边(Margins)和标记(Markers)

代码折叠是现代IDE和代码编辑器的必备功能,如果现在推出一个不支持折叠的编辑器,那是要被BS地~~。为了不被BS,很有必要先“研究”一下Scintilla的页边(Margins)和标记(Markers)功能。

  • 页 边(Margins):页边是位于文本显示区左边的一竖条区域,它可以用于显示行号、书签、断点标记等东东。Scintilla最多可以有5个页边(从左 到右的编号为0~4),每个页边可以使用SCI_SETMARGINTYPEN命令确定是用于显示行号还是符号。我们可以用 SCI_SETMARGINWIDTHN命令控制一个页边的宽度,如果设置为0,则表示不显示该页边。默认是只显示宽度为16的1号页边。
  • 标 记(Markers):标记,不用说也知道是用来标记文本位置(确切地说,是文本行)的。我们可以使用32种标记(编号0~31),我们可以自由决定这 32种标记的意义,如标记0用来表示断点、标记1~10表示书签、标记20表示语法错误行等等。不过,如果编辑器要支持代码折叠功能,我们得把标记 25~31留出来,把这7个标记作为代码折叠专用标记(后面还会讲到)。

告诉页边显示哪些标记

当页边不是设定为显示行号时(由SCI_SETMARGINTYPEN命令设置),那么它就会显示标记。刚才说过Scintilla有32种标记,一般来说不会让一个页边来显示所有的标记,而是只显示部分标记。

在一个页边里可以显示哪几种标记由SCI_SETMARGINMASKN命令设置,它的参数是一个32位掩码(mask)值,掩码值的第n位为1时表示该页边可显示n号标记。

所有页边相关的命令以SCI_SETMARGIN或SCI_GETMARGIN作为前缀,如:

  • SCI_SETMARGINTYPEN(int margin, int type)  设置页边显示行号还是符号,type可以是SC_MARGIN_SYMBOL或SC_MARGIN_NUMBER
  • SCI_SETMARGINWIDTHN(int margin, int pixelWidth)  设置页边宽度
  • SCI_SETMARGINMASKN(int margin, int mask)  设置页边掩码
  • SCI_SETMARGINSENSITIVEN(int margin, bool sensitive)  设置页边是否接受鼠标点击事件

所有标记相关的命令以SCI_MARKER作为前缀,如:

  • SCI_MARKERADD(int line, int markerNumber)  在指定行加入一个markerNumber号标记
  • SCI_MARKERDEFINE(int markerNumber, int markerSymbols)  定义markerNumber号标记的样式
  • SCI_MARKERDELETE(int line, int markerNumber) 在指定行上的删除markerNumber号标记
  • SCI_MARKERDELETEALL(int markerNumber) 删除文本中所有markerNumber号标记
  • SCI_MARKERSETFORE(int markerNumber, int colour) 为markerNumber号标记指定前景色
  • SCI_MARKERSETBACK(int markerNumber, int colour) 为markerNumber号标记指定背景色

演示代码

  1. // 标记和页边演示
  2. void TForm1::example()
  3. {
  4.     // 先写10行文本上去
  5.     for(int i=0; i<10; i++)
  6.         SendEditor(SCI_APPENDTEXT, 12, (sptr_t)"hello world ");
  7.     // 0号页边,宽度为9,显示0号标记(0..0001B)
  8.     SendEditor(SCI_SETMARGINTYPEN,0,SC_MARGIN_SYMBOL);
  9.     SendEditor(SCI_SETMARGINWIDTHN,0, 9);
  10.     SendEditor(SCI_SETMARGINMASKN,0, 0x01);
  11.     // 1号页边,宽度为9,显示1,2号标记(0..0110B)
  12.     SendEditor(SCI_SETMARGINTYPEN,1, SC_MARGIN_SYMBOL);
  13.     SendEditor(SCI_SETMARGINWIDTHN,1, 9);
  14.     SendEditor(SCI_SETMARGINMASKN,1, 0x06);
  15.     // 2号页边,宽度为20,显示行号
  16.     SendEditor(SCI_SETMARGINTYPEN,2, SC_MARGIN_NUMBER);
  17.     SendEditor(SCI_SETMARGINWIDTHN,2, 20);
  18.  
  19.     for(int i=0; i<10; i++)
  20.     {
  21.         // 前10行分别加入0~2号标记
  22.         SendEditor(SCI_MARKERADD, i, i%3);
  23.     }
  24.  
  25.     // 设置标记的前景色
  26.     SendEditor(SCI_MARKERSETFORE,0,0x0000ff);//0-红色
  27.     SendEditor(SCI_MARKERSETFORE,1,0x00ff00);//1-绿色
  28.     SendEditor(SCI_MARKERSETFORE,2,0xff0000);//2-蓝色
  29. }

显示效果是:

\

如果你不喜欢这些圆圈,可以用SCI_MARKERDEFINE命令改变标记的样式,可选的有:

SC_MARK_CIRCLE, SC_MARK_ROUNDRECT, SC_MARK_ARROW, SC_MARK_SMALLRECT,
SC_MARK_SHORTARROW, SC_MARK_EMPTY, SC_MARK_ARROWDOWN, SC_MARK_MINUS,
SC_MARK_PLUS, SC_MARK_VLINE, SC_MARK_LCORNER, SC_MARK_TCORNER, SC_MARK_BOXPLUS,
SC_MARK_BOXPLUSCONNECTED, SC_MARK_BOXMINUS, SC_MARK_BOXMINUSCONNECTED,
SC_MARK_LCORNERCURVE, SC_MARK_TCORNERCURVE, SC_MARK_CIRCLEPLUS,
SC_MARK_CIRCLEPLUSCONNECTED, SC_MARK_CIRCLEMINUS, SC_MARK_CIRCLEMINUSCONNECTED,
SC_MARK_BACKGROUND, SC_MARK_DOTDOTDOT, SC_MARK_ARROWS, SC_MARK_PIXMAP,
SC_MARK_FULLRECT, SC_MARK_LEFTRECT, SC_MARK_CHARACTER

默认是SC_MARK_CIRCLE,小圆圈。你可以试试其它的。(注意SC_MARK_CHARACTER比较特殊,它和一个ASCII码加起来决定标记显示为一个对应的ASCII字符)

有了这些基础,我们可以动手为Scintilla加入代码折叠功能了...

加载中
返回顶部
顶部