现在的位置: 首页 > 综合 > 正文

Scintilla开源库使用指南(一)

2013年10月03日 ⁄ 综合 ⁄ 共 3464字 ⁄ 字号 评论关闭

摘自:http://www.cnblogs.com/superanyi/archive/2011/04/07/2008632.html 

Scintilla是一个免费、跨平台、支持语法高亮的编辑控件。它完整支持源代码的编辑和调试,包括语法高亮、错误指示、代码完成(code completion)和调用提示(call tips)。能包含标记(marker)的页边(margin)可用于标记断点、折叠和高亮当前行。

Scintilla是一个免费、跨平台、支持语法高亮的编辑控件。它完整支持源代码的编辑和调试,包括语法高亮、错误指示、代码完成 (code completion)和调用提示(call tips)。能包含标记(marker)的页边(margin)可用于标记断点、折叠和高亮当前行。

可以从这里下载Scintilla库:http://scintilla.sourceforge.net/ScintillaDownload.html

这里有Scinilla相关的库下载,比如wxStyledTextCtrl就是Scintilla的wxWidgets移植版。http://www.scintilla.org/ScintillaRelated.html

另外,Scintilla的作者为了演示这个东东的功能,编写了一个叫SciTE的演示程序。不过这个程序的功能已经强大到足以作为我 们的常用代码编辑器,很值得下载下来学习学习。

老规矩,还是从编译说起

偶只在Windows下编译过,所以只好说说Windows环境下的编译方法。对于Linux,没试过(丢人-_-)

下载、解压略过不提

首先进入scintilla的win32目录:

cd scintilla\win32
  • 对于mingw,输入:
    mingw32-make
  • 对于VC6以上版本,输入:
    nmake -f scintilla.mak
  • 对于VC6(没试过,从Readme里看来的),输入:
    nmake -f scintilla_vc6.mak
  • 对于C++Builder,输入:
    make -fscintilla.mak

编译完成后,在bin目录里会得到Scintilla.dll和SciLexer.dll文件,SciLexer.dll是包含了语法解析器 (Lexer)的Scintilla控件,一般来说我们只要用它就可以了。

需要说明的是,不管是用什么编译器生成的DLL文件,都可以供给其它编译器使用(就象系统DLL一样,任何编译器都能使用),所以不用为各种编译器都编译 一份。

如果觉得生成的SciLexer.dll太大的话,可以考虑去除自带的部分语法解析器。比如你打算只用它来高亮C++代码的话,可以:

  1. 进到src目录里,移除除LexCPP.cxx以外的所有Lex*.cxx文件
  2. 执行LexGen.py重建make文件和KeyWords.cxx文件(需要安装Python)。
  3. 重新按前面的方法编译,这样生成的SciLexer.dll就只带有C++语法解析器了,体积也大小减小了(我VC编译的结果是从1.4M减小到 206K)。

启用Scintilla作为编辑控件

要启用Scintilla,首先当然是要加载之前编译的DLL文件啦~~

::LoadLibrary(_T("SciLexer.dll"));

SciLexer.dll加载后会自动以"Scintilla"作为类名注册一个窗体类,我们只要直接用这个类名建立窗体就可以了:

::CreateWindow(_T("Scintilla"),...);

演示(在C++Builder下编写)

由于Scintilla主要是窗体操作,为了减少不必要的窗体代码(主要是偷懒外加推广一下C++Builder,呵呵),这里使用C++Builder 来写演示程序。对于一些C++Builder的VCL库特有的东东,后面会有解释的。

首先新建一个窗体应用程序,

然后在WinMain里载入SciLexer.dll:

WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    LoadLibrary(_T("SciLexer.dll"));
    ...

最后,在TForm1的构造里建立Scintilla窗体:

#define SCINT_ID 1010
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { ::CreateWindow(_T("Scintilla"), NULL, WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE, 0,0,ClientWidth,ClientHeight, Handle, (HMENU)SCINT_ID, HInstance, NULL); }

很简单,是吧?对于Scintilla来说,没什么好解释的了。

这里主要给不了解C++Builder的童鞋介绍一下VCL的东东,以便于接下来的讲解和代码阅读(以及移植到其它编译器中)。

  • TForm1是一个C++Builder自动生成的窗体类,它继承自TForm,可以把它看成是WS_OVERLAPPEDWINDOW风格的HWND的 封装。
  • ClientWidth和ClientHeight是TForm的属性,看名字就知道它是客户区(ClientRect)的宽和高
  • Handle也是TForm的属性,就是该窗体的HWND
  • HInstance不用解释了吧,这是VCL的一个全局变量。

现在,我们的成果是这样的:


现在,看上去还比较土,接下来我们开始配置它,为使它成为可与VS媲美的代码编程器而战!

配置Scintilla的两种方法

配置Scintilla控件是通过向该控件发送配置命令实现的,各种配置命令可以在doc目录下找到(或者是这里http://scintilla.sourceforge.net/ScintillaDoc.html),后面的大部分事情都是在介绍这些配置命令。

有两种方法来发送配置命令,一种是直接使用SendMessage API。另一种是取得直接控制函数,通过函数来执行配置命令。

在Windows下,第二种方法要比第一种快得多。

直接控制函数的定义为:

typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);

后三个参数和SendMessage的后三个参数一样。

SciFnDirect的第一个参数用于指定具体的Scintilla窗体,它类似于窗体的HWND又不完全相同,姑且也称之为句柄吧。它是用一个配置命 令取得的,下面马上就要讲到。

取得直接控制函数和句柄的方法是:

SciFnDirect fnDirect = (SciFnDirect)SendMessage(hwndEditor,SCI_GETDIRECTFUNCTION,0,0);
sptr_t ptrDirect = (sptr_t)SendMessage(hwndEditor,SCI_GETDIRECTPOINTER,0,0);

取得这两样东西以后,就可以直接执行配置命令了,如:

m_fnDirect(fnDirect, SCI_CLEARALL, 0, 0);

演示代码:编写成员函数SendEditor,用于配置之前建立的Scintilla控件。

?
#include
<Scintilla.h>
#include
<SciLexer.h>
   
class TForm1
:
public TForm
{
__published:   //
IDE-managed Components
private:   //
User declarations
    SciFnDirect
m_fnDirect;
    sptr_t
m_ptrDirect;
public:       //
User declarations
    __fastcall
TForm1(TComponent* Owner);
    sptr_t
SendEditor(unsigned
int iMessage,
uptr_t wParam = 0, sptr_t lParam = 0)
    {
        return m_fnDirect(m_ptrDirect,
iMessage, wParam, lParam);
    }
};
   
#define
SCINT_ID 1010
__fastcall
TForm1::TForm1(TComponent* Owner)

抱歉!评论已关闭.