void
CScriptView::InitEditor( void )
{
s( SCI_CLEARDOCUMENTSTYLE );
s( SCI_SETCODEPAGE, SC_CP_UTF8 ); // 支持unicode
SetAStyle( STYLE_DEFAULT, black, white, 12, "Fixedsys" );
s( SCI_STYLECLEARALL ); // Copies global style to all others
// set the number of styling bits to 7 - the asp/html views need a lot of styling - default is 5
// If you leave the default you will see twiggle lines instead of ASP code
s( SCI_SETSTYLEBITS, 7 );
// tab宽度
s( SCI_SETTABWIDTH, 4 );
s( SCI_SETFOCUS, true );
// Snooper 语法解析
//SendEditor( SCI_SETLEXER, SCLEX_SNOOPER_APDU_NOCASE );
s( SCI_SETLEXERLANGUAGE, 0, reinterpret_cast( "snooper_apdu_nocase" ) );
s( SCI_SETKEYWORDS, 0, reinterpret_cast( g____apdu_keywords ) );//设置关键字
s( SCI_SETKEYWORDS, 1, reinterpret_cast( g____apdu_pre_keywords ) );//设置关键字
s( SCI_SETKEYWORDS, 2, reinterpret_cast( g____apdu_function_list ) );//设置关键字
SetAStyle( SCE_SS_DEFAULT, RGB( 0x00, 0x00, 0x00 ) ); // 默认
SetAStyle( SCE_SS_COMMENT, RGB( 0x00, 0x80, 0x80 ) ); // 注释
SetAStyle( SCE_SS_LABEL, RGB( 0X00, 0X80, 0X40 ), (~RGB( 0X00, 0X80, 0X40 ) & 0xffffff) ); // 标号
SetAStyle( SCE_SS_HEX_WRONG, RGB( 50, 100, 45 ) ); // 不是偶数个的hex串
// 当前行高亮
s( SCI_SETCARETLINEVISIBLE, TRUE );
//SendEditor( SCI_SETCARETLINEBACK, 0xb0ffff );
s( SCI_SETCARETLINEBACK, RGB( 226, 217, 232 ) );
// 括号匹配颜色
s( SCI_STYLESETBACK, STYLE_BRACELIGHT, RGB( 0x00, 0xFF, 0x00 ) );
//s( SCI_STYLESETBACK, STYLE_BRACEBAD, RGB( 0xFF, 0x00, 0x00 ) );
// 选择背景
s( SCI_SETSELBACK, true, RGB(0x9f,0xbb,0xe8) );
// 设置margin 0
s( SCI_SETMARGINTYPEN, 0, SC_MARGIN_NUMBER );
// 设置margin 1
s( SCI_SETMARGINTYPEN, 1, SC_MARGIN_SYMBOL );
// 掩码
s( SCI_SETMARGINMASKN, 1, 3 ); // bit 0 and bit 1
s( SCI_MARKERSETFORE, 0, RGB( 0xff, 0x00, 0x00 ) ); //1-red
s( SCI_MARKERSETFORE, 1, RGB( 0x00, 0xff, 0x00 ) ); //1-绿色
s( SCI_SETMARGINWIDTHN, 1, 9 );
// 接受鼠标点击
//s( SCI_SETMARGINSENSITIVEN, true );
//s( SCI_TEXTWIDTH(STYLE_LINENUMBER, "_99999") );
// 设置mouse hover时间
s( SCI_SETMOUSEDWELLTIME, 500 );
}
语法高亮之后,就是代码自动提示与自动完成
先用scintilla派生一个类,俺这个类叫editor,再建个view,嵌入这个editor,这样就可以在view中处理editor的大部分事件了。
代码提示,vc用'.'或'->'或'::'来呼叫,俺自己做这个就用.来呼叫函数列表了,在输入'(', ',', ')'是检查函数是否完成,进行参数提示,按F1或鼠标晃过去显示。
俺在UpdateUI中完成的参数提示,只要当前光标左边是一个'.',就显示函数列表
case SCN_UPDATEUI:
// 更新界面
UpdateUI();
break;
void
CScriptView::UpdateUI( void )
{
long lStart = s(SCI_GETCURRENTPOS, 0, 0);
int ch = s( SCI_GETCHARAT, lStart - 1 );
if( '.' == ch )
{
s( SCI_AUTOCSHOW, 0, (sptr_t)g____apdu_function_list );
}
唯一不足的就是前面多了一个'.',俺在自动完成的时候给删掉了。
参数提示
参数提示是在消息charadded时进行计算的,基本过程就是取得当前行的内容,再取得当前caret的位置,再再取得行首caret的位置,来计算当前caret对应行内的偏移量
snooper的表达式与其他不同,函数可嵌套,并且'(', '<', '{' 都有不同的意义,所以计算流程没有通用性。
BOOL
CScriptView::GetFunction( int pos_x, char *funpara, int *start, int *end )
{
int line_num = s( SCI_LINEFROMPOSITION, pos_x ); // 当前行
int line_length = s( SCI_LINELENGTH, line_num ); // 当前行长度
// 下面几句相当重要噢,取得行内偏移量
int pos0 = s( SCI_FINDCOLUMN, line_num, 0 ); // 取得当前行的最左边位置的开始pos
int pos;
pos = pos_x - pos0; // 在行内的偏移量,从1开始