Document directory
- Old Rules: Let's start with compilation.
- Enable Scintilla as the editing Control
- Two Methods for configuring Scintilla
- Enable Scintilla to support syntax highlighting
Scintilla is a free, cross-platform editing control that supports syntax highlighting. It supports source code editing and debugging, including syntax highlighting, Error Indication, code completion, and call tips ). Margin can be used to mark breakpoints, collapse, and highlight the current row.
Scintilla is a free, cross-platform editing control that supports syntax highlighting. It supports source code editing and debugging, including syntax highlighting, Error Indication, code completion, and call tips ). Margin can be used to mark breakpoints, collapse, and highlight the current row.
Download Scintilla Library: http://scintilla.sourceforge.net/ScintillaDownload.html from here
Download Scinilla-related libraries. For example, wxScintilla is the wxWidgets porting version of Scintilla. Http://www.scintilla.org/ScintillaRelated.html
In addition, the author of Scintilla compiled a demonstration program called SciTE to demonstrate the functions of this stuff. However, this program is powerful enough to serve as our common code editor. It is worth learning and downloading.
Old Rules: Let's start with compilation.
I have compiled only in Windows, so I have to talk about the compiling method in Windows. I have never tried Linux (shame -_-)
Download and decompress
First, go to the win32 Directory of scintilla:
cd scintilla\win32
After compilation is complete, Scintilla will be obtained in the bin directory. dll and SciLexer. dll file, SciLexer. dll is a Scintilla control that contains the syntax Parser (Lexer). Generally, we only need to use it.
It should be noted that no matter what compiler is used to generate the DLL file, it can be used by other compilers (just like system DLL, any compiler can use it ), therefore, you do not need to compile a copy for all compilers.
If you think the generated SciLexer. dll is too large, you can consider removing part of the built-in syntax parser. For example, if you want to use it to highlight C ++ code, you can:
- Go to the src directory and remove all Lex *. cxx files except LexCPP. cxx.
- Execute LexGen. py to recreate the make file and KeyWords. cxx file (Python needs to be installed ).
- Recompile according to the previous method to generate SciLexer. the dll only carries the C ++ syntax parser, And the size is reduced (the result of my VC compilation is reduced from 1.4M to 206 K ).
Enable Scintilla as the editing Control
To enable Scintilla, you must first load the previously compiled DLL file ~~
::LoadLibrary(_T("SciLexer.dll"));
After SciLexer. dll is loaded, it automatically registers a form class with "Scintilla" as the class name. We just need to create a form using this class name:
::CreateWindow(_T("Scintilla"),...);Demo (written in C ++ Builder)
Because Scintilla is mainly a form operation, in order to reduce unnecessary form code (mainly to be lazy and promote C ++ Builder, haha), Here C ++ Builder is used to write the demo program. Some VCL libraries specific to C ++ Builder will be explained later.
First, create a form application,
Then load SciLexer. dll in WinMain:
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){ LoadLibrary(_T("SciLexer.dll")); ...
Finally, create the Scintilla form in the TForm1 structure:
#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);}
Very simple, right? For Scintilla, there is no better explanation.
Here we will introduce VCL to kids shoes who do not know C ++ Builder, so as to facilitate the subsequent explanations and code reading (and porting to other compilers ).
- TForm1 is a form class automatically generated by C ++ Builder. It inherits from TForm and can be viewed as an encapsulation of WS_OVERLAPPEDWINDOW-style HWND.
- ClientWidth and ClientHeight are the attributes of the TForm. You can see the width and height of the ClientRect.
- Handle is also a TForm attribute, that is, the HWND OF THE FORM
- HInstance does not need to be explained. This is a global variable of VCL.
Our results are as follows:
Now, it looks quite earthy. Next we will start to configure it to make it a code programmer comparable to!
Two Methods for configuring Scintilla
The Scintilla control is configured by sending configuration commands to the control, various configuration commands can be found in the doc directory (or here the http://scintilla.sourceforge.net/ScintillaDoc.html), most of the subsequent things are about these configuration commands.
There are two methods to send configuration commands, one is to directly use the SendMessage API. The other is to obtain the direct control function and execute the configuration command through the function.
In Windows, the second method is much faster than the first one.
The direct control function is defined:
typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
The last three parameters are the same as those of SendMessage.
The first parameter of SciFnDirect is used to specify a specific Scintilla form. It is similar to the HWND of the form, but it is also called a handle. It is obtained using a configuration command, which will be discussed soon.
The method for obtaining direct control functions and handles is:
SciFnDirect fnDirect = (SciFnDirect)SendMessage(hwndEditor,SCI_GETDIRECTFUNCTION,0,0);sptr_t ptrDirect = (sptr_t)SendMessage(hwndEditor,SCI_GETDIRECTPOINTER,0,0);
After obtaining these two items, you can directly execute the configuration command, for example:
m_fnDirect(fnDirect, SCI_CLEARALL, 0, 0);
DEMO code: Compile the member function SendEditor to configure the previously created Scintilla control.
#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) : TForm(Owner) { HWND hwndEditor = ::CreateWindow(_T("Scintilla"), NULL, WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE, 0,0,ClientWidth,ClientHeight, Handle, (HMENU)SCINT_ID, HInstance, NULL); m_fnDirect = (SciFnDirect)SendMessage(hwndEditor,SCI_GETDIRECTFUNCTION,0,0); m_ptrDirect = (sptr_t)SendMessage(hwndEditor,SCI_GETDIRECTPOINTER,0,0); } Enable Scintilla to support syntax highlighting
With the previous SendEditor control function, we can configure syntax highlighting. The following Code enables the Scintilla control to display the C ++ syntax highlighting code:
Const char * g_szKeywords = "asm auto bool break case catch char class const" "const_cast continue default delete do double" "dynamic_cast else enum explicit extern false finally" "float for friend goto if inline int long mutable "" namespace new operator private protected public "" register reinterpret_cast register return short signed "" sizeof static static_cast struct switch template "" this throw true try typedef typeid typename "" union unsigned using virtual void volatile "" wchar_t while ";... sendEditor (SCI_SETLEXER, SCLEX_CPP); // C ++ parses SendEditor (SCI_SETKEYWORDS, 0, (sptr_t) g_szKeywords ); // set the keyword // set the foreground color of various syntax elements SendEditor (SCI_STYLESETFORE, SCE_C_WORD, 0x00FF0000); // The keyword SendEditor (latency, SCE_C_STRING, 0x0015a3); // string SendEditor (latency, latency, SCE_C_CHARACTER, 0x001515A3); // SendEditor (delimiter, SCE_C_PREPROCESSOR, 0x00808080); // SendEditor (SCI_STYLESETFORE, SCE_C_COMMENT, 0x00008000 ); // block annotation SendEditor (SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x00008000); // line annotation SendEditor (SCI_STYLESETFORE, SCE_C_COMMENTDOC, 0x00008000); // document annotation (beginning)
To support syntax highlighting, you need to do three things: 1. Select a syntax parser.
The syntax parser is used to break a large piece of code into tokens. It is also used to control code folding (which will be discussed later ).
The command for the selected syntax parser is SCI_SETLEXER, for example:
SendEditor(SCI_SETLEXER, SCLEX_CPP);
In addition to SCLEX_CPP, there are also a lot of SCLEX_HTML, SCLEX_PERL, SCLEX_ SQL, SCLEX_VB and so on, which are defined in SciLexer. h. Modern IDE should be able to locate the SCLEX_CPP definition. The SCLEX_XXX around it is another syntax parser.
You can also use the SCI_SETLEXERLANGUAGE command, for example:
SendEditor(SCI_SETLEXERLANGUAGE, 0, (sptr_t)"cpp");
SCI_SETLEXERLANGUAGE accepts a string parameter, which is defined in the line of code starting with LexerModule at the end of the Code parser source code (src \ lex *. cxx), where the third parameter is.
Ii. Set keywords
Syntax Parsing is only responsible for splitting the code. We have to specify the keywords.
This method brings some flexibility. For example, we want to highlight a custom language. The style of this language is similar to that of C ++ (such as Java, C #, php, etc ), you can also select SCLEX_CPP as the syntax parser and define your own keywords. (So you do not need to compile all the Resolvers into the DLL file)
The command for setting the keyword is SCI_SETKEYWORDS. Its wParam is used to specify the keyword type, which can be 0 ~ 8 is 9 types, so that we can make a more detailed distinction, such as distinguishing the keywords for if and int bool. LParam specifies the keyword, which is separated by spaces.
3. Set the font style corresponding to the text element
That is, Font, foreground color, background color, italic bold, etc.
Set the font style command with SCI_STYLE as the prefix, this group of commands are more, in order not to waste space, I will only list a few, other can refer to here (http://scintilla.sourceforge.net/ScintillaDoc.html#StyleDefinition ).
SCI_STYLESETBACK (int styleNumber, int color) // sets the background color SCI_STYLESETFORE (int styleNumber, int color) // sets the foreground color SCI_STYLESETFONT (int styleNumber, char * fontName) // set the font SCI_STYLESETSIZE (int styleNumber, int sizeInPoints) // set the font size SCI_STYLESETBOLD (int styleNumber, bool bold) // set the bold
StyleNumber refers to text elements, such as keywords, row numbers, and control strings. In the preceding code, SCE_C_XXXX is a syntax-related element decomposed by the C ++ parser. There are also STYLE_DEFAULT (default), STYLE_LINENUMBER (row number), STYLE_BRACELIGHT (matching brackets), STYLE_BRACEBAD (matching brackets), STYLE_CONTROLCHAR (control character), STYLE_INDENTGUIDE (indent line), STYLE_CALLTIP (call prompt ).
SCI_STYLECLEARALL // set all text elements to the same style as STYLE_DEFAULT
The recommended sequence in the Scintilla document is to first set some general styles to STYLE_DEFAULT, then use SCI_STYLECLEARALL to reset the style of all elements to be consistent with STYLE_DEFAULT, and finally set other elements separately.
Demo: Our Editor supports C ++ highlighting!
# Include <Scintilla. h> # include <SciLexer. h>... void TForm1: setCppStyle () {const char * szKeywords1 = "asm auto break case catch class const" "const_cast continue default delete do double" "dynamic_cast else enum explicit extern false" "for friend goto if inline mutable "" namespace new operator private protected public "" register reinterpret_cast return signed "" sizeof static static_cast struct switch template "" this throw true try typedef typeid typename "" union unsigned using virtual volatile while "; const char * szKeywords2 = "bool char float int long short void wchar_t"; // set the global style SendEditor (timer, STYLE_DEFAULT, (sptr_t) "Courier New"); SendEditor (SCI_STYLESETSIZE, STYLE_DEFAULT, 10); SendEditor (plaintext); // C ++ syntax parse SendEditor (SCI_SETLEXER, SCLEX_CPP); SendEditor (SCI_SETKEYWORDS, 0, (sptr_t) szKeywords1 ); // set the keyword SendEditor (SCI_SETKEYWORDS, 1, (sptr_t) szKeywords2); // set the keyword // set the SendEditor (SCI_STYLESETFORE, SCE_C_WORD, 0x00FF0000) for various syntax element styles ); // keyword SendEditor (latency, SCE_C_WORD2, 0x00800080); // keyword SendEditor (SCI_STYLESETBOLD, SCE_C_WORD2, TRUE); // keyword SendEditor (latency, SCE_C_STRING, 0x001515A3 ); // string SendEditor (delimiter, SCE_C_CHARACTER, 0x0015a3); // character SendEditor (delimiter, SCE_C_PREPROCESSOR, 0x00808080); // The SendEditor (SCI_STYLESETFORE, SCE_C_COMMENT, 0x00008000); // block annotation SendEditor (SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x00008000); // line annotation SendEditor (SCI_STYLESETFORE, SCE_C_COMMENTDOC, 0x00008000 ); // document annotation (beginning with/**) SendEditor (SCI_SETCARETLINEVISIBLE, TRUE); SendEditor (latency, 0xb0ffff);} _ fastcall TForm1: TForm1 (TComponent * Owner ): TForm (Owner ){... setCppStyle ();}
It looks good. If you want to, you can add the current line highlighting function:
SendEditor(SCI_SETCARETLINEVISIBLE, TRUE);SendEditor(SCI_SETCARETLINEBACK, 0xb0ffff);
Finally, we recommend that you change the TAB width from 8 to 4 by default (according to your habits ~~)
SendEditor(SCI_SETTABWIDTH, 4);
Our results are as follows: