上一次曾经发布过一篇如何实现一个代码编辑器。今年工做中得空,因此对这个编辑器进一步作了些更新,把名字改为了从CuteC改为了CEditor。主要是重写了软件的界面(最终还原朴素),重写了编辑控件语法高亮的着色方式,还有增长了一个简单的SSH客户端和SFTP文件编辑的功能。感受基本的功能已经实现了,因此再次写点东西记录一下。而且发布一下编辑控件的源代码,有兴趣的可下载下来看看,虽然代码写得比较乱。
上个版本:http://www.cnblogs.com/linxr/archive/2011/10/30/2229256.html
编辑控件源码连接:http://files.cnblogs.com/linxr/LEdit.rar
软件下载连接:http://files.cnblogs.com/linxr/CEditor.rar
软件界面:
html
1、编辑控件
除了上一次写到的一些内容外,主要在编辑控件的语法高亮上作了修改。
1. 原来的颜色信息是在绘制每行时,动态分词查找关键字,造成一个颜色数组供绘制模块使用。这种方式的优势就是逻辑简单,绘制代码很容易编写。可是缺点就是,每次绘制一行,都要从新产生颜色数组,影响效率;其二,在一些场合下,高亮不是依赖于关键字,这时候这种方法就无能为力了。
2. 考虑到上面的缺点,对编辑控件作了修改。去除了颜色数组,改用标注信息来标注颜色字体信息。因此行数据通过着色以后再也不是原来的内容了。
例如一行数据:
int main( int argc, char ** argv );
那么通过着色后,该行的数据会变成:
\ec3,0~int\ezc~ main( \ec3,0~int\ezc~ argc, \ec3,0~char\ezc~ ** argv );
其中,int和char被着色,标注信息为:
\ec3,0~ 和 \ezc~
着色信息以\e(0x1b)开始,以~结束。c表示颜色,z表示还原格式格式。
着色完成后,绘制模块在进行绘制文本信息时,从头至尾,扫描字符串,根据着色信息,不断的设置还原DC的颜色信息,直到绘制完成。
3. 标注颜色带来了一些额外的问题,主要表如今:
a.光标位置到字符串中的位置的转换的计算。
b.获取编辑器的内容时,要清除全部的标注信息,影响必定的性能。
c.计算tab键的宽度时,不能用tab键在字符串中的位置来计算,要考虑标注信息。
d.光标在屏幕中的位置的计算,要根据光标前面数据的字体来实时计算宽度。
2、函数列表
对于代码编辑软件来讲,函数符号列表功能是必备的,就算是纯写C的人来讲,有一个函数列表会大大提升滚动查找代码的效率。我虽然写了一个C语言的解释器,对符号的解析稍做修改就能够实现,可是各类各样的语言,我就无能为力了。好在有ctags.exe,他能够支持很是的语言符号分析。我仍是直接拿来用吧,而后再加上一个树形控件,就能实现简单实用的功能。
我调用ctags.exe的代码片断,主要是调用了ctags.exe,将结果保存到一个文件,而后咱们再解析这个文件:
CString strParam;
CString strTags = strFilePath + _T(".tags.txt");
strParam.Format( _T("-f \"%s\" --language-force=C++ -n \"%s\"" ), strTags.GetBuffer(0), strFilePath.GetBuffer(0) );windows
SHELLEXECUTEINFO sei;
ZeroMemory( &sei, sizeof(SHELLEXECUTEINFO) );
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.hwnd = NULL;
sei.lpVerb = NULL;
sei.lpFile = "ctags.exe";
sei.lpParameters = strParam.GetBuffer(0);
sei.lpDirectory = CLxrFile::GetExecutePath().GetBuffer(0);
sei.nShow = SW_HIDE;
sei.hInstApp = NULL;
ShellExecuteEx(&sei);
WaitForSingleObject( sei.hProcess, INFINITE );
/*
** 能够看到就是调用了ShellExecuteEx,可是有几个地方能够提一下:
** 1. sei.nShow = SW_HIDE; 这使得进程启动时不会显示控制台窗口。
** 2. WaitForSingleObject( sei.hProcess, INFINITE );
** 等待进程结束,这个很重要,否则ctags启动后,咱们没法同步获取结果。
*/
ctags.exe支持的语言,能够用命令 ctags.exe --list-languages 查看:
Asm
Asp
Awk
Basic
BETA
C
C++
C#
Cobol
Eiffel
Erlang
Fortran
HTML
Java
JavaScript
Lisp
Lua
Make
Pascal
Perl
PHP
Python
REXX
Ruby
Scheme
Sh
SLang
SML
SQL
Tcl
Vera
Verilog
Vim
YACC
能够看到,他几乎涵盖了全部流行的语言,而他的执行文件大小只有256kb,太强悍了,让我很是的佩服。api
3、脚本管理
让编辑软件支持脚本是必要的,不只仅能够对经常使用的功能提供扩展。我实现了类C的解析执行,因此对简单的计算功能,软件的功能,都能给外部脚本提供接口函数,让脚本轻松的操做编辑器,或者作一些好玩的事情。我主要作的是将脚本直接映射到右键菜单,当添加一个脚本时,他将直接被添加进右键菜单。而且支持多级目录。
例如,我实现了几个接口供脚本使用:
int ceditor_exe_2( char * cmd, char * out );
该函数用于执行cmd指令,out为输出结果。cmd为编辑器的的命令,形如rep_sel$hello world$。
int ceditor_exe_4( char * cmd, char * p1, char *p2, char * out );
该函数效果同ceditor_exe_2,可是cmd仅是命令,p1,p2分别是两个参数。
int clear();
该函数用于清除输出框的内容。
int ceditor_hotkey( char * ctrlKeys, int vKey, char * scriptPath );
该函数用于注册热键。数组
C的解释器,你们能够看我之前发过的文章,代码能够在CSDN上面找到,搜索"xrc C语言解释器"就能找到,或者试试这个连接:http://download.csdn.net/download/linxren/4204728。在cnblogs上能够看看相关的实现方法,算是讲得比较清楚的吧。
4、数据存储
数据存储在不一样的软件中都必须用到,我这里主要是配置的存储和脚本的存储,正好我写了个key-value存储系统,因此这个直接拿来用就很是合适了,效率也不错。跟直接读写硬盘没什么区别,省去了烦人的fopen,fread,fwrite,fclose调用,直接用windows的api更是烦人,因此写这样一个简单的库,很是方便。
http://www.cnblogs.com/linxr/p/3252541.html,在这里能够看到实现方法和下载到源代码。我以为这个简单的key-value存储库,比我写的解释器,和这个编辑器自己更加实用,全部的软件均可以用,接口也很简单。没法就是open,set,get,close四个函数。省去了文件操做的各类麻烦。编辑器