中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站指向ip列表是什么全國(guó)最好的廣告公司加盟

網(wǎng)站指向ip列表是什么,全國(guó)最好的廣告公司加盟,成都工程網(wǎng)站建設(shè),網(wǎng)站被墻怎么做跳轉(zhuǎn)Scintilla是一個(gè)免費(fèi)、跨平臺(tái)、支持語(yǔ)法高亮的編輯控件。它完整支持源代碼的編輯和調(diào)試,包括語(yǔ)法高亮、錯(cuò)誤指示、代碼完成(code completion)和調(diào)用提示(call tips)。能包含標(biāo)記(marker)的頁(yè)邊(margin&…

Scintilla是一個(gè)免費(fèi)、跨平臺(tái)、支持語(yǔ)法高亮的編輯控件。它完整支持源代碼的編輯和調(diào)試,包括語(yǔ)法高亮、錯(cuò)誤指示、代碼完成(code?completion)和調(diào)用提示(call?tips)。能包含標(biāo)記(marker)的頁(yè)邊(margin)可用于標(biāo)記斷點(diǎn)、折疊和高亮當(dāng)前行。

Scintilla是一個(gè)免費(fèi)、跨平臺(tái)、支持語(yǔ)法高亮的編輯控件。它完整支持源代碼的編輯和調(diào)試,包括語(yǔ)法高亮、錯(cuò)誤指示、代碼完成 (code completion)和調(diào)用提示(call tips)。能包含標(biāo)記(marker)的頁(yè)邊(margin)可用于標(biāo)記斷點(diǎn)、折疊和高亮當(dāng)前行。

可以從這里下載Scintilla庫(kù):http://scintilla.sourceforge.net/ScintillaDownload.html

這里有Scinilla相關(guān)的庫(kù)下載,比如wxScintilla就是Scintilla的wxWidgets移植版。http://www.scintilla.org/ScintillaRelated.html

另外,Scintilla的作者為了演示這個(gè)東東的功能,編寫(xiě)了一個(gè)叫SciTE的演示程序。不過(guò)這個(gè)程序的功能已經(jīng)強(qiáng)大到足以作為我 們的常用代碼編輯器,很值得下載下來(lái)學(xué)習(xí)學(xué)習(xí)。

老規(guī)矩,還是從編譯說(shuō)起

偶只在Windows下編譯過(guò),所以只好說(shuō)說(shuō)Windows環(huán)境下的編譯方法。對(duì)于Linux,沒(méi)試過(guò)(丟人-_-)

下載、解壓略過(guò)不提

首先進(jìn)入scintilla的win32目錄:

cd scintilla\win32
  • 對(duì)于mingw,輸入:
    mingw32-make

    ?

  • 對(duì)于VC6以上版本,輸入:
    nmake -f scintilla.mak

    ?

  • 對(duì)于VC6(沒(méi)試過(guò),從Readme里看來(lái)的),輸入:
    nmake -f scintilla_vc6.mak

    ?

  • 對(duì)于C++Builder,輸入:
    make -fscintilla.mak

    ?

編譯完成后,在bin目錄里會(huì)得到Scintilla.dll和SciLexer.dll文件,SciLexer.dll是包含了語(yǔ)法解析器 (Lexer)的Scintilla控件,一般來(lái)說(shuō)我們只要用它就可以了。

需要說(shuō)明的是,不管是用什么編譯器生成的DLL文件,都可以供給其它編譯器使用(就象系統(tǒng)DLL一樣,任何編譯器都能使用),所以不用為各種編譯器都編譯 一份。

如果覺(jué)得生成的SciLexer.dll太大的話,可以考慮去除自帶的部分語(yǔ)法解析器。比如你打算只用它來(lái)高亮C++代碼的話,可以:

  1. 進(jìn)到src目錄里,移除除LexCPP.cxx以外的所有Lex*.cxx文件
  2. 執(zhí)行LexGen.py重建make文件和KeyWords.cxx文件(需要安裝Python)。
  3. 重新按前面的方法編譯,這樣生成的SciLexer.dll就只帶有C++語(yǔ)法解析器了,體積也大小減小了(我VC編譯的結(jié)果是從1.4M減小到 206K)。

啟用Scintilla作為編輯控件

要啟用Scintilla,首先當(dāng)然是要加載之前編譯的DLL文件啦~~

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

SciLexer.dll加載后會(huì)自動(dòng)以"Scintilla"作為類(lèi)名注冊(cè)一個(gè)窗體類(lèi),我們只要直接用這個(gè)類(lèi)名建立窗體就可以了:

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

演示(在C++Builder下編寫(xiě))

由于Scintilla主要是窗體操作,為了減少不必要的窗體代碼(主要是偷懶外加推廣一下C++Builder,呵呵),這里使用C++Builder 來(lái)寫(xiě)演示程序。對(duì)于一些C++Builder的VCL庫(kù)特有的東東,后面會(huì)有解釋的。

首先新建一個(gè)窗體應(yīng)用程序,

然后在WinMain里載入SciLexer.dll:

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

最后,在TForm1的構(gòu)造里建立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);
}

很簡(jiǎn)單,是吧?對(duì)于Scintilla來(lái)說(shuō),沒(méi)什么好解釋的了。

這里主要給不了解C++Builder的童鞋介紹一下VCL的東東,以便于接下來(lái)的講解和代碼閱讀(以及移植到其它編譯器中)。

  • TForm1是一個(gè)C++Builder自動(dòng)生成的窗體類(lèi),它繼承自TForm,可以把它看成是WS_OVERLAPPEDWINDOW風(fēng)格的HWND的 封裝。
  • ClientWidth和ClientHeight是TForm的屬性,看名字就知道它是客戶(hù)區(qū)(ClientRect)的寬和高
  • Handle也是TForm的屬性,就是該窗體的HWND
  • HInstance不用解釋了吧,這是VCL的一個(gè)全局變量。

?

配置Scintilla的兩種方法

配置Scintilla控件是通過(guò)向該控件發(fā)送配置命令實(shí)現(xiàn)的,各種配置命令可以在doc目錄下找到(或者是這里http://scintilla.sourceforge.net/ScintillaDoc.html),后面的大部分事情都是在介紹這些配置命令。

有兩種方法來(lái)發(fā)送配置命令,一種是直接使用SendMessage API。另一種是取得直接控制函數(shù),通過(guò)函數(shù)來(lái)執(zhí)行配置命令。

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

直接控制函數(shù)的定義為:

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

后三個(gè)參數(shù)和SendMessage的后三個(gè)參數(shù)一樣。
SciFnDirect的第一個(gè)參數(shù)用于指定具體的Scintilla窗體,它類(lèi)似于窗體的HWND又不完全相同,姑且也稱(chēng)之為句柄吧。它是用一個(gè)配置命 令取得的,下面馬上就要講到。

取得直接控制函數(shù)和句柄的方法是:

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

取得這兩樣?xùn)|西以后,就可以直接執(zhí)行配置命令了,如:

m_fnDirect(fnDirect, SCI_CLEARALL, 0, 0);

演示代碼:編寫(xiě)成員函數(shù)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)?: 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);?}

讓Scintilla支持語(yǔ)法高亮

有了前面的SendEditor控制函數(shù),我們就可以配置語(yǔ)法高亮了,下面這段代碼可以使我們的Scintilla控件顯示C++語(yǔ)法高亮代碼:

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++語(yǔ)法解析
SendEditor(SCI_SETKEYWORDS, 0, (sptr_t)g_szKeywords);//設(shè)置關(guān)鍵字
// 下面設(shè)置各種語(yǔ)法元素前景色
SendEditor(SCI_STYLESETFORE, SCE_C_WORD, 0x00FF0000);
//關(guān)鍵字SendEditor(SCI_STYLESETFORE, SCE_C_STRING, 0x001515A3);//字符串
SendEditor(SCI_STYLESETFORE, SCE_C_CHARACTER, 0x001515A3);//字符
SendEditor(SCI_STYLESETFORE, SCE_C_PREPROCESSOR, 0x00808080);//預(yù)編譯開(kāi)關(guān)
SendEditor(SCI_STYLESETFORE, SCE_C_COMMENT, 0x00008000);//塊注釋
SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x00008000);//行注釋
SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTDOC, 0x00008000);//文檔注釋(/**開(kāi)頭)

要支持語(yǔ)法高亮,要做三件事:

一、選定語(yǔ)法解析器

語(yǔ)法解析器用于把一大段代碼分解成一個(gè)個(gè)的單詞(token),另外還用于代碼折疊的控制(后面會(huì)說(shuō)到)。

選定語(yǔ)法解析器的命令是SCI_SETLEXER,如:

SendEditor(SCI_SETLEXER, SCLEX_CPP);

除了SCLEX_CPP以外,還有SCLEX_HTML、SCLEX_PERL、SCLEX_SQL、SCLEX_VB等一大堆,定 義在SciLexer.h里?,F(xiàn)代的IDE應(yīng)該可以定位SCLEX_CPP定義,它周?chē)腟CLEX_XXX就是其它的語(yǔ)法解析器。

另外,也可以用SCI_SETLEXERLANGUAGE命令,如:

SendEditor(SCI_SETLEXERLANGUAGE, 0, (sptr_t)"cpp");

SCI_SETLEXERLANGUAGE接受的是一個(gè)字符串參數(shù),這個(gè)字符串定義于代碼解析器源代碼(src\lex*.cxx) 最后面LexerModule開(kāi)頭的那行代碼,那里的第三個(gè)參數(shù)就是。

二、設(shè)置關(guān)鍵字

語(yǔ)法解析只負(fù)責(zé)把代碼拆分開(kāi),至于哪些是關(guān)鍵字,還得我們來(lái)指定。

這種方式帶來(lái)了些許的靈活性,比如我們要高亮一種自定義的語(yǔ)言,這種語(yǔ)言的風(fēng)格與C++類(lèi)似(如Java、C#、php等),我們也 可以選定SCLEX_CPP作為語(yǔ)法解析器,然后定義自己的關(guān)鍵字。(所以不需要把各種解析器都編譯進(jìn)DLL文件里)

設(shè)置關(guān)鍵字的命令是SCI_SETKEYWORDS。它的wParam用于指定關(guān)鍵字種類(lèi),可以是0~8即9種類(lèi)型,這樣我們可以做 更細(xì)致的區(qū)分,如把關(guān)鍵字for if和int bool區(qū)分顯示。lParam指定關(guān)鍵字,以空格分隔。?? ?

三、設(shè)置文本元素對(duì)應(yīng)的字體風(fēng)格

即字體、前景色、背景色、斜體粗體等

設(shè)置字體風(fēng)格的命令以SCI_STYLE作為前綴,這組命令比較多,為了不浪費(fèi)篇幅,偶這里只列舉幾個(gè),其它的可以參考這里?(http://scintilla.sourceforge.net/ScintillaDoc.html#StyleDefinition)。

SCI_STYLECLEARALL?//把所有文本元素設(shè)置成與STYLE_DEFAULT相同的風(fēng)格

這里的styleNumber是指文本元素,如關(guān)鍵字、行號(hào)、控制字串等。前面代碼中的SCE_C_XXXX是C++解析器分解出的 語(yǔ)法相關(guān)的元素。另外還有STYLE_DEFAULT(默認(rèn))、STYLE_LINENUMBER(行號(hào))、STYLE_BRACELIGHT(括號(hào)匹 配)、STYLE_BRACEBAD(括號(hào)失配)、STYLE_CONTROLCHAR(控制字符)、STYLE_INDENTGUIDE(縮進(jìn)線)、 STYLE_CALLTIP(調(diào)用提示)。

Scintilla文檔建議的順序是先向STYLE_DEFAULT設(shè)置一些通用風(fēng)格,然后再用SCI_STYLECLEARALL 把所有元素風(fēng)格重置成與STYLE_DEFAULT一致,最后單獨(dú)設(shè)置其它元素。

演示,我們的編輯器支持C++高亮啦!

?

看上去不錯(cuò),如果你愿意,還可以加上當(dāng)前行高亮功能:

?

SendEditor(SCI_SETCARETLINEVISIBLE, TRUE);

SendEditor(SCI_SETCARETLINEBACK, 0xb0ffff);

最后,建議把TAB寬度由默認(rèn)的8改為4(依個(gè)人習(xí)慣~~)?

?

SendEditor(SCI_SETTABWIDTH, 4);

現(xiàn)在,我們的成果是這樣的:

#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";?// 設(shè)置全局風(fēng)格?SendEditor(SCI_STYLESETFONT, STYLE_DEFAULT,(sptr_t)"Courier New");?SendEditor(SCI_STYLESETSIZE, STYLE_DEFAULT,10);?SendEditor(SCI_STYLECLEARALL);?//C++語(yǔ)法解析?SendEditor(SCI_SETLEXER, SCLEX_CPP);?SendEditor(SCI_SETKEYWORDS, 0, (sptr_t)szKeywords1);//設(shè)置關(guān)鍵字?SendEditor(SCI_SETKEYWORDS, 1, (sptr_t)szKeywords2);//設(shè)置關(guān)鍵字?// 下面設(shè)置各種語(yǔ)法元素風(fēng)格?SendEditor(SCI_STYLESETFORE, SCE_C_WORD, 0x00FF0000);???//關(guān)鍵字?SendEditor(SCI_STYLESETFORE, SCE_C_WORD2, 0x00800080);???//關(guān)鍵字?SendEditor(SCI_STYLESETBOLD, SCE_C_WORD2, TRUE);???//關(guān)鍵字?SendEditor(SCI_STYLESETFORE, SCE_C_STRING, 0x001515A3);?//字符串?SendEditor(SCI_STYLESETFORE, SCE_C_CHARACTER, 0x001515A3);?//字符?SendEditor(SCI_STYLESETFORE, SCE_C_PREPROCESSOR, 0x00808080);//預(yù)編譯開(kāi)關(guān)?SendEditor(SCI_STYLESETFORE, SCE_C_COMMENT, 0x00008000);//塊注釋?SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTLINE, 0x00008000);//行注釋?SendEditor(SCI_STYLESETFORE, SCE_C_COMMENTDOC, 0x00008000);//文檔注釋(/**開(kāi)頭)?SendEditor(SCI_SETCARETLINEVISIBLE, TRUE);?SendEditor(SCI_SETCARETLINEBACK, 0xb0ffff);?}?__fastcall TForm1::TForm1(TComponent* Owner)?: TForm(Owner)?{?...?setCppStyle();?}

這里繼續(xù)學(xué)習(xí)Scintilla更多的控制命令和實(shí)現(xiàn)細(xì)節(jié),完善我們的編輯器;

頁(yè)邊(Margins)和標(biāo)記(Markers)

代碼折疊是現(xiàn)代IDE和代碼編輯器的必備功能,如果現(xiàn)在推出一個(gè)不支持折疊的編輯器,那是要被BS地~~。為了不被BS,很有必要先“研究”一下Scintilla的頁(yè)邊(Margins)和標(biāo)記(Markers)功能。

  • 頁(yè) 邊(Margins):頁(yè)邊是位于文本顯示區(qū)左邊的一豎條區(qū)域,它可以用于顯示行號(hào)、書(shū)簽、斷點(diǎn)標(biāo)記等東東。Scintilla最多可以有5個(gè)頁(yè)邊(從左 到右的編號(hào)為0~4),每個(gè)頁(yè)邊可以使用SCI_SETMARGINTYPEN命令確定是用于顯示行號(hào)還是符號(hào)。我們可以用 SCI_SETMARGINWIDTHN命令控制一個(gè)頁(yè)邊的寬度,如果設(shè)置為0,則表示不顯示該頁(yè)邊。默認(rèn)是只顯示寬度為16的1號(hào)頁(yè)邊。
  • 標(biāo) 記(Markers):標(biāo)記,不用說(shuō)也知道是用來(lái)標(biāo)記文本位置(確切地說(shuō),是文本行)的。我們可以使用32種標(biāo)記(編號(hào)0~31),我們可以自由決定這 32種標(biāo)記的意義,如標(biāo)記0用來(lái)表示斷點(diǎn)、標(biāo)記1~10表示書(shū)簽、標(biāo)記20表示語(yǔ)法錯(cuò)誤行等等。不過(guò),如果編輯器要支持代碼折疊功能,我們得把標(biāo)記 25~31留出來(lái),把這7個(gè)標(biāo)記作為代碼折疊專(zhuān)用標(biāo)記(后面還會(huì)講到)。

告訴頁(yè)邊顯示哪些標(biāo)記

當(dāng)頁(yè)邊不是設(shè)定為顯示行號(hào)時(shí)(由SCI_SETMARGINTYPEN命令設(shè)置),那么它就會(huì)顯示標(biāo)記。剛才說(shuō)過(guò)Scintilla有32種標(biāo)記,一般來(lái)說(shuō)不會(huì)讓一個(gè)頁(yè)邊來(lái)顯示所有的標(biāo)記,而是只顯示部分標(biāo)記。

在一個(gè)頁(yè)邊里可以顯示哪幾種標(biāo)記由SCI_SETMARGINMASKN命令設(shè)置,它的參數(shù)是一個(gè)32位掩碼(mask)值,掩碼值的第n位為1時(shí)表示該頁(yè)邊可顯示n號(hào)標(biāo)記。

所有頁(yè)邊相關(guān)的命令以SCI_SETMARGIN或SCI_GETMARGIN作為前綴,如:

  • SCI_SETMARGINTYPEN(int margin, int type)? 設(shè)置頁(yè)邊顯示行號(hào)還是符號(hào),type可以是SC_MARGIN_SYMBOL或SC_MARGIN_NUMBER
  • SCI_SETMARGINWIDTHN(int margin, int pixelWidth)? 設(shè)置頁(yè)邊寬度
  • SCI_SETMARGINMASKN(int margin, int mask)? 設(shè)置頁(yè)邊掩碼
  • SCI_SETMARGINSENSITIVEN(int margin, bool sensitive)? 設(shè)置頁(yè)邊是否接受鼠標(biāo)點(diǎn)擊事件

所有標(biāo)記相關(guān)的命令以SCI_MARKER作為前綴,如:

  • SCI_MARKERADD(int line, int markerNumber)? 在指定行加入一個(gè)markerNumber號(hào)標(biāo)記
  • SCI_MARKERDEFINE(int markerNumber, int markerSymbols)? 定義markerNumber號(hào)標(biāo)記的樣式
  • SCI_MARKERDELETE(int line, int markerNumber) 在指定行上的刪除markerNumber號(hào)標(biāo)記
  • SCI_MARKERDELETEALL(int markerNumber) 刪除文本中所有markerNumber號(hào)標(biāo)記
  • SCI_MARKERSETFORE(int markerNumber, int colour) 為markerNumber號(hào)標(biāo)記指定前景色
  • SCI_MARKERSETBACK(int markerNumber, int colour) 為markerNumber號(hào)標(biāo)記指定背景色
    // 標(biāo)記和頁(yè)邊演示?void?TForm1::example()?{?// 先寫(xiě)10行文本上去?for(int?i=0; i<10; i++)?SendEditor(SCI_APPENDTEXT, 12, (sptr_t)"hello world ");?// 0號(hào)頁(yè)邊,寬度為9,顯示0號(hào)標(biāo)記(0..0001B)?SendEditor(SCI_SETMARGINTYPEN,0,SC_MARGIN_SYMBOL);?SendEditor(SCI_SETMARGINWIDTHN,0, 9);?SendEditor(SCI_SETMARGINMASKN,0, 0x01);?// 1號(hào)頁(yè)邊,寬度為9,顯示1,2號(hào)標(biāo)記(0..0110B)?SendEditor(SCI_SETMARGINTYPEN,1, SC_MARGIN_SYMBOL);?SendEditor(SCI_SETMARGINWIDTHN,1, 9);?SendEditor(SCI_SETMARGINMASKN,1, 0x06);?// 2號(hào)頁(yè)邊,寬度為20,顯示行號(hào)?SendEditor(SCI_SETMARGINTYPEN,2, SC_MARGIN_NUMBER);?SendEditor(SCI_SETMARGINWIDTHN,2, 20);?for(int?i=0; i<10; i++)?{?// 前10行分別加入0~2號(hào)標(biāo)記?SendEditor(SCI_MARKERADD, i, i%3);?}?// 設(shè)置標(biāo)記的前景色?SendEditor(SCI_MARKERSETFORE,0,0x0000ff);//0-紅色?SendEditor(SCI_MARKERSETFORE,1,0x00ff00);//1-綠色?SendEditor(SCI_MARKERSETFORE,2,0xff0000);//2-藍(lán)色?}

    ?

?

如果你不喜歡這些圓圈,可以用SCI_MARKERDEFINE命令改變標(biāo)記的樣式,可選的有:

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

默認(rèn)是SC_MARK_CIRCLE,小圓圈。你可以試試其它的。(注意SC_MARK_CHARACTER比較特殊,它和一個(gè)ASCII碼加起來(lái)決定標(biāo)記顯示為一個(gè)對(duì)應(yīng)的ASCII字符)

有了這些基礎(chǔ),我們可以動(dòng)手為Scintilla加入代碼折疊功能了...

為Scintilla加入代碼折疊功能

前面曾說(shuō)過(guò)當(dāng)編輯器有代碼折疊功能時(shí),25號(hào)到31號(hào)這7個(gè)標(biāo)記是作為代碼折疊專(zhuān)用標(biāo)記的。在scintilla.h中,我們可以找到它們的定義:

#define SC_MARKNUM_FOLDEREND 25  //折疊狀態(tài)(多級(jí)中間)
#define SC_MARKNUM_FOLDEROPENMID 26  //展開(kāi)狀態(tài)(多級(jí)中間)
#define SC_MARKNUM_FOLDERMIDTAIL 27  //被折疊代碼塊尾部(多級(jí)中間)
#define SC_MARKNUM_FOLDERTAIL 28  //被折疊代碼塊尾部
#define SC_MARKNUM_FOLDERSUB 29   //被折疊的代碼塊
#define SC_MARKNUM_FOLDER 30     //折疊狀態(tài)
#define SC_MARKNUM_FOLDEROPEN 31 //展開(kāi)狀態(tài)
顯示這些標(biāo)記的掩碼是0xFE000000,同樣頭文件里已經(jīng)定義好了
#define SC_MASK_FOLDERS 0xFE000000

要加入代碼折疊功能,還有一個(gè)最最關(guān)鍵的事情,就是要得到語(yǔ)法解析器(Lexer)的支持,上面的這些標(biāo)記都是由語(yǔ)法解析器自動(dòng)添加刪除的。一般來(lái)說(shuō),只要用下面這條命令就可以了讓語(yǔ)法解析器支持代碼折疊了:

SendEditor(SCI_SETPROPERTY,(sptr_t)"fold",(sptr_t)"1");

?

?

這里TForm1::WndProc方法是Scintilla父窗體即我們的TForm1的窗口處理函數(shù)。

代碼折疊以后我們要通過(guò)點(diǎn)擊頁(yè)邊上的+和-標(biāo)記來(lái)打開(kāi)和折疊代碼,所以需要頁(yè)邊接收鼠標(biāo)點(diǎn)擊事件:

這里TForm1::WndProc方法是Scintilla父窗體即我們的TForm1的窗口處理函數(shù)。

代碼折疊以后我們要通過(guò)點(diǎn)擊頁(yè)邊上的+和-標(biāo)記來(lái)打開(kāi)和折疊代碼,所以需要頁(yè)邊接收鼠標(biāo)點(diǎn)擊事件:

SendEditor(SCI_SETMARGINSENSITIVEN, MARGIN_FOLD_INDEX, TRUE); //響應(yīng)鼠標(biāo)消息

這樣,當(dāng)有鼠標(biāo)點(diǎn)擊該頁(yè)邊后,Scintilla就會(huì)向它的父窗體發(fā)送代碼為SCN_MARGINCLICK的WM_NOTIFY消息,其中的LParam為SCNotification*類(lèi)型。關(guān)于SCNotification的詳細(xì)信息請(qǐng)參考這里。SCNotification的position成員指出了點(diǎn)擊位置對(duì)應(yīng)的行號(hào),最后我們用SCI_TOGGLEFOLD命令折疊或展開(kāi)代碼。

使用自定義圖形

Scintilla自帶的標(biāo)記樣式和VS比起來(lái)還有差距,反正偶是怎么調(diào)都覺(jué)得有點(diǎn)土。Scintilla允許我們自己定義標(biāo)記的樣式,方法是:

  1. 用SCI_MARKERDEFINE命令設(shè)置標(biāo)記的樣式為SC_MARK_PIXMAP
  2. 用SCI_MARKERDEFINEPIXMAP命令設(shè)置標(biāo)記使用的圖形,這里的圖形要求是xpm格式。

怎樣得到xpm格式圖形

xpm在linux系統(tǒng)下用得比較多,它和BMP、jpg一樣也是一種圖片格式,有不少工具可以把圖片轉(zhuǎn)換成xpm格式的,比如我喜歡的免費(fèi)看圖軟件XnView就可以,想必ACDSee也行吧。

xpm比較特殊的地方是它可以作為頭文件直接被C語(yǔ)言調(diào)用,吃驚吧?用文本編輯器打開(kāi)它看看,呵呵,其實(shí)它就是一個(gè)數(shù)組定義。

如下面這個(gè)數(shù)據(jù)(代碼)就是后面馬上就要用到的minus.xpm和plus.xpm圖片文件的內(nèi)容(從eclipse里挖出來(lái)的):

#define MARGIN_FOLD_INDEX 2?void?TForm1::setFold()?{?SendEditor(SCI_SETPROPERTY,(sptr_t)"fold",(sptr_t)"1");?SendEditor(SCI_SETMARGINTYPEN, MARGIN_FOLD_INDEX, SC_MARGIN_SYMBOL);//頁(yè)邊類(lèi)型?SendEditor(SCI_SETMARGINMASKN, MARGIN_FOLD_INDEX, SC_MASK_FOLDERS);?//頁(yè)邊掩碼?SendEditor(SCI_SETMARGINWIDTHN, MARGIN_FOLD_INDEX, 11);?//頁(yè)邊寬度?SendEditor(SCI_SETMARGINSENSITIVEN, MARGIN_FOLD_INDEX, TRUE);?//響應(yīng)鼠標(biāo)消息?// 折疊標(biāo)簽樣式?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_CIRCLEPLUS);??SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_CIRCLEMINUS);??SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND,? SC_MARK_CIRCLEPLUSCONNECTED);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_CIRCLEMINUSCONNECTED);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNERCURVE);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);??SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNERCURVE);?// 折疊標(biāo)簽顏色?SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERSUB, 0xa0a0a0);?SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERMIDTAIL, 0xa0a0a0);?SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERTAIL, 0xa0a0a0);?SendEditor(SCI_SETFOLDFLAGS, 16|4, 0);?//如果折疊就在折疊行的上下各畫(huà)一條橫線?}?__fastcall TForm1::TForm1(TComponent* Owner)?: TForm(Owner)?{?...?setFold();?}?void?__fastcall TForm1::WndProc(Messages::TMessage &Message)?{?TForm::WndProc(Message);?if(Message.Msg == WM_NOTIFY){?SCNotification* notify = (SCNotification*)Message.LParam;?if(notify->nmhdr.code == SCN_MARGINCLICK &&?notify->nmhdr.idFrom == SCINT_ID){?// 確定是頁(yè)邊點(diǎn)擊事件?const?int?line_number = SendEditor(SCI_LINEFROMPOSITION,notify->position);?SendEditor(SCI_TOGGLEFOLD, line_number);?}?}?}

演示,使用自定義圖形:

#include "minus.xpm"?#include "plus.xpm"?void?TForm1::setFold()?{?...?// 折疊標(biāo)簽樣式?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_PIXMAP);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_PIXMAP);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND,? SC_MARK_PIXMAP);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_PIXMAP);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNERCURVE);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);?SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNERCURVE);?//?SendEditor(SCI_MARKERDEFINEPIXMAP, SC_MARKNUM_FOLDER, (sptr_t)plus_xpm);?SendEditor(SCI_MARKERDEFINEPIXMAP, SC_MARKNUM_FOLDEROPEN, (sptr_t)minus_xpm);?SendEditor(SCI_MARKERDEFINEPIXMAP, SC_MARKNUM_FOLDEREND, (sptr_t)plus_xpm);?SendEditor(SCI_MARKERDEFINEPIXMAP, SC_MARKNUM_FOLDEROPENMID, (sptr_t)minus_xpm);?...?}

?

怎樣支持自動(dòng)縮進(jìn)

在VS里編寫(xiě)C++代碼時(shí),輸入回車(chē)換行后會(huì)保持和上一行的縮進(jìn)一致,輸入"{'字符后回車(chē)還會(huì)幫我們多縮進(jìn)一次,輸入'}'后又能自動(dòng)退回。我們的編輯器也要實(shí)現(xiàn)這個(gè)功能。

現(xiàn)在再仔細(xì)了解一下Scintilla的通知消息(http://scintilla.sourceforge.net/ScintillaDoc.html#Notifications),除了前面用到的頁(yè)邊點(diǎn)擊事件外,還有很多事件非常有用。

實(shí)現(xiàn)自動(dòng)縮進(jìn)功能我們要關(guān)心的事件通知是SCN_CHARADDEDSCN_UPDATEUI。

  • 當(dāng)用戶(hù)輸入一個(gè)字符時(shí),SCN_CHARADDED事件觸發(fā),SCNotification的ch成員保存了輸入的字符。
  • 當(dāng)更新文檔界面時(shí),SCN_UPDATEUI事件觸發(fā)。輸入字符,改變字體風(fēng)格,改變選區(qū)都會(huì)引起界面更新

演示代碼

改寫(xiě)TForm1::WndProc,處理這兩個(gè)事件,我們的編輯器支持自動(dòng)縮進(jìn)啦

void?__fastcall TForm1::WndProc(Messages::TMessage &Message)?{?TForm::WndProc(Message);?if(Message.Msg == WM_NOTIFY)?{?...?// 處理自動(dòng)縮進(jìn)?static?int?LastProcessedChar = 0;?//在CharAdded事件中記錄最后輸入的字符?if(notify->nmhdr.code == SCN_CHARADDED)?{?LastProcessedChar = notify->ch;?}?// 在UpdateUI事件中處理縮進(jìn)?if(notify->nmhdr.code == SCN_UPDATEUI && LastProcessedChar!=0)?{?int?pos = SendEditor(SCI_GETCURRENTPOS);?//取得當(dāng)前位置?int?line = SendEditor(SCI_LINEFROMPOSITION,pos);?//取得當(dāng)前行?//如果最后輸入的字符是右括號(hào)的話就自動(dòng)讓當(dāng)前行縮進(jìn)和它匹配的左括號(hào)所在行一致?if(?strchr("})>]",LastProcessedChar) &&?isspace(SendEditor(SCI_GETCHARAT,pos-2)) &&?//要求右括號(hào)左邊是空白字符?LastProcessedChar!=0)?{?//找前一個(gè)單詞起始位置,這里用它來(lái)確定右括號(hào)左邊是否全是空白字符?int?startpos = SendEditor(SCI_WORDSTARTPOSITION,pos-1,false);?int?linepos = SendEditor(SCI_POSITIONFROMLINE,line);?//當(dāng)前行起始位置?if(startpos == linepos)?//這樣相當(dāng)于判斷右括號(hào)左邊是否全是空白字符?{?int?othpos = SendEditor(SCI_BRACEMATCH,pos-1);?//得到對(duì)應(yīng)的左括號(hào)所在的位置?int?othline = SendEditor(SCI_LINEFROMPOSITION,othpos);??//左括號(hào)所在行?int?nIndent = SendEditor(SCI_GETLINEINDENTATION,othline);//左括號(hào)所在行的縮進(jìn)值?// 替換右括號(hào)前面的空白字符,使之與左括號(hào)縮進(jìn)一致?char?space[1024];?memset(space,' ',1024);?SendEditor(SCI_SETTARGETSTART, startpos);?SendEditor(SCI_SETTARGETEND, pos-1);?SendEditor(SCI_REPLACETARGET,nIndent,(sptr_t)space);?}?}?// 如果輸入的是回車(chē),則保持與上一行縮進(jìn)一致?// 如果上一行最后有效字符為左括號(hào),就多縮進(jìn)四個(gè)空格?if(LastProcessedChar ==?' ')?{?if(line > 0)?{?// 得到上一行縮進(jìn)設(shè)置?int?nIndent = SendEditor(SCI_GETLINEINDENTATION,line-1);?// 查找上一行最后一個(gè)有效字符(非空白字符)?int?nPrevLinePos = SendEditor(SCI_POSITIONFROMLINE,line-1);?int?c =?' ';?for(int?p = pos-2;?p>=nPrevLinePos &&?isspace(c);?p--, c=SendEditor(SCI_GETCHARAT,p));?// 如果是左括號(hào),就多縮進(jìn)四格?if(c &&?strchr("{([<",c)) nIndent+=4;?// 縮進(jìn)...?char?space[1024];?memset(space,' ',1024);?space[nIndent] = 0;?SendEditor(SCI_REPLACESEL, 0, (sptr_t)space);?}?}?LastProcessedChar = 0;?}?}?}

下面是代碼中用到的Scintilla命令的簡(jiǎn)單介紹

  • SCN_CHARADDED事件記錄最后輸入的字符,在SCN_UPDATEUI事件中處理縮進(jìn)。
  • 當(dāng)輸入回車(chē)時(shí)(LastProcessedChar == ' '),我們只需要保證新行和前一行的縮進(jìn)相同就可以了。
  • SCI_GETLINEINDENTATION命令可以取得指定行的縮進(jìn)數(shù)(即行首的空格數(shù)目)。
  • SCI_REPLACESEL命令用指定字符串替換選擇區(qū)域
  • SCI_GETCURRENTPOS命令取得當(dāng)前位置
  • SCI_GETCHARAT命令取得指定位置的字符
  • SCI_LINEFROMPOSITION命令取得指定位置所在的行號(hào)
  • SCI_POSITIONFROMLINE命令取得指定行號(hào)的起始位置
  • SCI_WORDSTARTPOSITION命令取得指定位置所在單詞的起始位置,如xxx|xx,(|代表指定位置),那么它會(huì)返回|xxxxx的位置。同樣還有SCI_WORDENDPOSITION命令。
  • SCI_BRACEMATCH取得括號(hào)的另一半位置,如指定位置的字符是'}'時(shí),它返回匹配的'{'所在的位置。
  • SCI_SETTARGETSTART和SCI_SETTARGETEND設(shè)置TARGET的起始和始止位置,SCI_REPLACETARGET命令用指定字符串替換TARGET指定范圍內(nèi)的字符。

VS的代碼完成和函數(shù)提示功能是很值得稱(chēng)道的,它們可以極大地提高我們的編程效率(造成我現(xiàn)在寫(xiě)代碼時(shí)往往只記住前四個(gè)字母,如果在對(duì)象后面點(diǎn)了小數(shù)點(diǎn)后不出現(xiàn)提示就會(huì)心慌意亂的說(shuō)-_-),盡管有時(shí)也會(huì)失效。

做為IDE這個(gè)功能是絕對(duì)不能少D。即使你只打算做個(gè)編輯器,如果有這個(gè)功能那也是一大亮點(diǎn)啊~~(目前很多代碼編輯器都沒(méi)這個(gè)功能的說(shuō))。

關(guān)于函數(shù)提示的幾個(gè)命令以SCI_CALLTIP作為前綴,這里只介紹我們即將使用的幾個(gè)命令(更多命令見(jiàn):http://scintilla.sourceforge.net/ScintillaDoc.html#CallTips)

  • SCI_CALLTIPSHOW(int posStart, const char *definition) 顯示提示。posStart表示顯示位置,definition是顯示的內(nèi)容
  • SCI_CALLTIPCANCEL 取消提示
  • SCI_CALLTIPACTIVE 如果當(dāng)前編輯器中有提示信息,返回1,否則返回0
  • SCI_CALLTIPSETHLT(int highlightStart, int highlightEnd) 設(shè)置提示中的高亮位置,在VS里我們輸入函數(shù)實(shí)參時(shí)函數(shù)提示會(huì)高亮當(dāng)前輸入的參數(shù)名。

在我們程序中加入提示的最佳時(shí)機(jī)是SCN_CHARADDED(見(jiàn)上一節(jié))事件。當(dāng)用戶(hù)輸入左圓括號(hào)'('時(shí),取得括號(hào)左邊的函數(shù)名,然后顯示出該函數(shù)的完整定義。

下面的代碼實(shí)現(xiàn)了CreateWindow和MoveWindow兩個(gè)API的函數(shù)提示

//我們要高亮的兩個(gè)函數(shù)?const?size_t?FUNCSIZE=2;?char* g_szFuncList[FUNCSIZE]={?//函數(shù)名?"CreateWindow(",?"MoveWindow("?};?char* g_szFuncDesc[FUNCSIZE]={?//函數(shù)信息?"HWND CreateWindow("?"LPCTSTR lpClassName,"?" LPCTSTR lpWindowName,"?" DWORD dwStyle, "?" int x,"?" int y,"?" int nWidth,"?" int nHeight, "?" HWND hWndParent,"?" HMENU hMenu,"?" HANDLE hInstance,"?" PVOID lpParam"?")",?"BOOL MoveWindow("?"HWND hWnd,"?" int X,"?" int Y,"?" int nWidth,"?" int nHeight,"?" BOOL bRepaint"?")"?};?void?__fastcall TForm1::WndProc(Messages::TMessage &Message)?{?TForm::WndProc(Message);?if(Message.Msg == WM_NOTIFY)?{?SCNotification* notify = (SCNotification*)Message.LParam;?...?if(notify->nmhdr.code == SCN_CHARADDED)?{?...?// 函數(shù)提示功能?static?const?char* pCallTipNextWord = NULL;//下一個(gè)高亮位置?static?const?char* pCallTipCurDesc = NULL;//當(dāng)前提示的函數(shù)信息?if(notify->ch ==?'(')?//如果輸入了左括號(hào),顯示函數(shù)提示?{?char?word[1000];?//保存當(dāng)前光標(biāo)下的單詞(函數(shù)名)?TextRange tr;????//用于SCI_GETTEXTRANGE命令?int?pos = SendEditor(SCI_GETCURRENTPOS);?//取得當(dāng)前位置(括號(hào)的位置)?int?startpos = SendEditor(SCI_WORDSTARTPOSITION,pos-1);//當(dāng)前單詞起始位置?int?endpos = SendEditor(SCI_WORDENDPOSITION,pos-1);//當(dāng)前單詞終止位置?tr.chrg.cpMin = startpos;??//設(shè)定單詞區(qū)間,取出單詞?tr.chrg.cpMax = endpos;?tr.lpstrText = word;?SendEditor(SCI_GETTEXTRANGE,0, sptr_t(&tr));?for(size_t?i=0; i<FUNCSIZE; i++)?//找找有沒(méi)有我們認(rèn)識(shí)的函數(shù)??{?if(memcmp(g_szFuncList[i],word,sizeof(g_szFuncList[i])) == 0)?{?????//找到啦,那么顯示提示吧?pCallTipCurDesc = g_szFuncDesc[i];?//當(dāng)前提示的函數(shù)信息?SendEditor(SCI_CALLTIPSHOW,pos,sptr_t(pCallTipCurDesc));//顯示這個(gè)提示?const?char?*pStart =?strchr(pCallTipCurDesc,'(')+1;?//高亮第一個(gè)參數(shù)?const?char?*pEnd =?strchr(pStart,',');//參數(shù)列表以逗號(hào)分隔?if(pEnd == NULL) pEnd =?strchr(pStart,')');//若是最后一個(gè)參數(shù),后面是右括號(hào)?SendEditor(SCI_CALLTIPSETHLT,?pStart-pCallTipCurDesc, pEnd-pCallTipCurDesc);?pCallTipNextWord = pEnd+1;//指向下一參數(shù)位置?break;?}?}?}?else?if(notify->ch ==?')')?//如果輸入右括號(hào),就關(guān)閉函數(shù)提示?{?SendEditor(SCI_CALLTIPCANCEL);?pCallTipCurDesc = NULL;?pCallTipNextWord = NULL;?????????????????}?else?if(notify->ch ==?','?&& SendEditor(SCI_CALLTIPACTIVE) && pCallTipCurDesc)?{?//輸入的是逗號(hào),高亮下一個(gè)參數(shù)?const?char?*pStart = pCallTipNextWord;?const?char?*pEnd =?strchr(pStart,',');?if(pEnd == NULL) pEnd =?strchr(pStart,')');?if(pEnd == NULL)?//沒(méi)有下一個(gè)參數(shù)啦,關(guān)閉提示?SendEditor(SCI_CALLTIPCANCEL);?else?{?SendEditor(SCI_CALLTIPSETHLT,pStart-pCallTipCurDesc, pEnd-pCallTipCurDesc);?pCallTipNextWord = pEnd+1;?}?}?}//if(notify->nmhdr.code == SCN_CHARADDED)?...?}//if(Message.Msg == WM_NOTIFY)?}

當(dāng)然,這個(gè)提示功能相當(dāng)山寨啦。比如函數(shù)名和括號(hào)之間有空格提示就不出來(lái)了,函數(shù)嵌套調(diào)用時(shí)只會(huì)提示最后一個(gè)函數(shù)的參數(shù)。關(guān)于如果改進(jìn),大家各顯神通吧。

另外,還有一個(gè)提外話,在實(shí)際的使用中,我們的函數(shù)信息不可能象這里一樣是寫(xiě)死的,而是依據(jù)用戶(hù)的輸入動(dòng)態(tài)生成的函數(shù)名及信息列表。這就涉及到一個(gè)C++代碼解析的問(wèn)題(還好,只要解析函數(shù)聲明就行了),對(duì)于這一點(diǎn),牛X的同學(xué)可以自己寫(xiě)解析代碼;次牛X的可以考慮用WAVE,Spirit,Regex等庫(kù)幫助解析;象偶這種不牛的同學(xué),則可以考慮利用CTAGS工具在后臺(tái)線程中生成tag文件,我們從tag文件里取就可以了(當(dāng)然,效率嘛~~可以參考C++Builder的函數(shù)提示效率-_-)。

代碼完成和函數(shù)提示的用法類(lèi)似,前綴是SCI_AUTOC,具體命令見(jiàn):http://scintilla.sourceforge.net/ScintillaDoc.html#Autocompletion

void?__fastcall TForm1::WndProc(Messages::TMessage &Message)?{?TForm::WndProc(Message);?if(Message.Msg == WM_NOTIFY)?{?...?if(notify->nmhdr.code == SCN_CHARADDED)?{?...?if(notify->ch ==?'.')?{?char?word[1000];?//保存當(dāng)前光標(biāo)下的單詞?TextRange tr;????//用于SCI_GETTEXTRANGE命令?int?pos = SendEditor(SCI_GETCURRENTPOS);?//取得當(dāng)前位置?int?startpos = SendEditor(SCI_WORDSTARTPOSITION,pos-1);//當(dāng)前單詞起始位置?int?endpos = SendEditor(SCI_WORDENDPOSITION,pos-1);//當(dāng)前單詞終止位置?tr.chrg.cpMin = startpos;??//設(shè)定單詞區(qū)間,取出單詞?tr.chrg.cpMax = endpos;?tr.lpstrText = word;?SendEditor(SCI_GETTEXTRANGE,0, sptr_t(&tr));?if(strcmp(word,"file.") == 0)?//輸入file.后提示file對(duì)象的幾個(gè)方法?{?SendEditor(SCI_AUTOCSHOW,0,?sptr_t(?"close "?"eof "?"good "?"open "?"rdbuf "?"size"?));?}?}?...

SCI_AUTOCSHOW命令的第一個(gè)參數(shù)表示已經(jīng)輸入了多少個(gè)字符。這對(duì)于代碼自動(dòng)完成是很有幫助的,比如我們可以用它幫助用戶(hù)輸入長(zhǎng)串的單詞,如:

if(strcmp(word,"Create") == 0)?{?SendEditor(SCI_AUTOCSHOW,6,//已經(jīng)輸入了6位字符?sptr_t(?"CreateBitmap "?"CreateDC "?"CreateHandle "?"CreateWindow "?"CreateWindowEx"?));?}

?

http://www.risenshineclean.com/news/6364.html

相關(guān)文章:

  • 網(wǎng)站運(yùn)維是做什么的所有關(guān)鍵詞
  • 如何搭建免費(fèi)網(wǎng)站seo推廣營(yíng)銷(xiāo)公司
  • 購(gòu)物網(wǎng)站做推廣銅仁搜狗推廣
  • 做網(wǎng)站只用php不用html馮耀宗seo視頻教程
  • 廈門(mén)建設(shè)銀行網(wǎng)站百度引擎搜索
  • 建網(wǎng)站的重要性網(wǎng)絡(luò)營(yíng)銷(xiāo)服務(wù)的內(nèi)容
  • 騰訊短鏈接生成seo褲子的關(guān)鍵詞首頁(yè)排名有哪些
  • 做買(mǎi)衣服的網(wǎng)站友情鏈接互換網(wǎng)站
  • app外包流程濰坊自動(dòng)seo
  • 成都制作網(wǎng)站寧波seo企業(yè)網(wǎng)絡(luò)推廣
  • 購(gòu)物網(wǎng)站建設(shè)思維導(dǎo)圖百度app官方正式版
  • php免費(fèi)網(wǎng)站系統(tǒng)電商seo是什么意思
  • 免費(fèi)網(wǎng)站代碼下載百度號(hào)碼
  • WordPress網(wǎng)站打不開(kāi)nginx百度一下了你就知道官網(wǎng)
  • 做介紹美食網(wǎng)站的菜單的企業(yè)seo整站優(yōu)化方案
  • 咋做網(wǎng)站代碼背景圖seo怎樣優(yōu)化網(wǎng)站
  • 網(wǎng)站解析查詢(xún)?nèi)W(wǎng)營(yíng)銷(xiāo)渠道
  • 淮南發(fā)布seo網(wǎng)站優(yōu)化培訓(xùn)公司
  • pa66用途障車(chē)做網(wǎng)站百度應(yīng)用商店下載安裝
  • 東莞公司網(wǎng)站開(kāi)發(fā)武漢網(wǎng)站設(shè)計(jì)十年樂(lè)云seo
  • 個(gè)性化定制網(wǎng)站公司宣傳軟文
  • 三好街做網(wǎng)站的公司百度搜索網(wǎng)站優(yōu)化
  • 如何在本地發(fā)布自己做的網(wǎng)站中國(guó)十大網(wǎng)站排名
  • 2021跨境電商最火的產(chǎn)品西安seo技術(shù)
  • 版式設(shè)計(jì)網(wǎng)站優(yōu)化人員通常會(huì)將目標(biāo)關(guān)鍵詞放在網(wǎng)站首頁(yè)中的
  • 網(wǎng)站集群建設(shè)廣告平臺(tái)
  • 網(wǎng)站查詢(xún)功能怎么做seo咨詢(xún)河北
  • 教育類(lèi)網(wǎng)站模板交換鏈接名詞解釋
  • 創(chuàng)業(yè)網(wǎng)站推廣怎么做seo最新優(yōu)化技術(shù)
  • 在網(wǎng)盤(pán)上怎么做自己的網(wǎng)站太原網(wǎng)站開(kāi)發(fā)