SynEdit系列的第三方控件是專門做代碼編輯器的,可以不用寫一行代碼,就可以實現基本的功能。
安裝方法:點我。
Tool Palette中可以看到安裝完的兩項:SynEdit, SynEdit Highlighters。
SynEdit中包含一些主要控件,包括SynEdit, SynMemo, DBSynEdit,SynMultiSyn,SynCompletionProposal等等。還有比如AutoComplete什么的沒用過,不過可以看看自帶的Demo。
SynEdit Highlighters包含的就是一些編程語言的語法高亮了,比如cpp, pas, bas, asm, java, JScript, HTML等等。
此外,SynEdit可以自定義Highlighter,但自定義需要理解所使用的語法(這個就需要看附帶的HTML了),還要SynEdit自帶的SynGen.exe設計並生成pas文件才能在Delphi引用。
=================================================================================================
SynEdit和SynMemo的常用屬性如下:
注:標明為“-”表示還不清楚怎么用
Align, Anchors, Contrains:同第二方控件。
BookmarkOptions:Bookmark相關設置
BookmarkImage:Bookmark顯示的圖片,留空為默認設置。DrawBookmarksFirst:-EnableKeys:允許通過快捷鍵添加Bookmark(KeyStrokes設置的快捷鍵默認為Ctrl+Shift+數字)。GlyphsVisible:不顯示Bookmark,但仍然可以跳轉到指定的Bookmark。LeftMargin:Bookmark和編輯器左邊緣距離。XOffset:Bookmark距離容器邊界的偏移量(待修改)。
BorderStyle:外邊框樣式
Color:文本框背景色
Gutter:邊欄設置
AutoSize:自動調整寬度。BorderColor:邊界線顏色。BorderStyle:邊界線樣式,有如下可選:gbsMiddle(默認), gbsNone和gbsRight。Color:顏色。Cursor:鼠標光標,無需修改。DigitCount:數字個數,可以和LeadingZero配合使用。此屬性僅在ShowLineNumbers為True可見,而且會影響Gutter的寬度。默認值為4。Gradient:漸變效果,需要GradientStart,GradientEnd和GradientSteps配合使用。GradientStart,GradientEnd:漸變顏色設置。GradientSteps:漸變程度(梯度),值越大效果越好,但不能太大。默認值為48。LeadingZeros:數字前面填0,僅在ShowLineNumbers為True時有效,且受DigitCount的影響。LeftOffset, RigthOffset:偏移量。LeftOffset的值過小可能會影響Bookmark的顯示。LineNumberStart:指定數字為第一行。但是ZeroStart為True時第一行仍然為0。ShowLineNumbers:顯示行數。此屬性默認為False。UseFontStyle:使用Gutter的Font屬性。如果為False則使用SynMemo或SynEdit的Font的設置。Visible:可見性。Width:寬度。ZeroStart:以0為第一行。僅在ShowLineNumbers為True時有效。
InsertCaret, OverwriteCaret:插入/改寫狀態下光標樣式
ctBlock:單個字符,通常用於Overwrite模式ctHalfBlock:半個字符ctHorizontalLine:水平光標顯示在字符底部ctVerticalLine:垂直光標,用於Insert模式
InsertMode:插入(Insert)/改寫(Overwrite)模式。
Keystrokes:包括一些常用功能,如:剪切、復制、粘貼、撤銷等。可添加刪除等。
MaxUndo:撤銷最大值
ReadOnly:只讀
RightEdge:右邊緣線位置
RightEdgeColor:右邊緣線顏色
WantTabs:允許使用Tab鍵縮進
ScrollBars:滾動條,一般不改
SelectionColor:選擇文本顏色
ScrollHintColor:行數提示顏色
ScrollHintFormat:行數提示格式
SelectionMode:選擇模式shfTopLineOnly:顯示范圍的第一行shfTopToBottom:同Windows 7資源管理器
TabWidth:Tab寬度,當WantTabs為True時有效smNormal:默認smLine:整行smColumn:指定矩形范圍
Options:
WordWrap:自動換行eoAltSetsColumnMode:按下Alt鍵時以矩形范圍選擇文本eoAutoIndent:換行自動縮進eoAutoSizeMaxScrollWidth:-eoDisableScrollArrows:禁用滾動條的箭頭eoDragDropEditing:允許拖拽移動、復制eoDropFiles:允許通過拖拽打開文件eoEnhanceHomeKey、eoEnhanceEndKey:當按下Home、End鍵將光標移動到文字最前/后方eoGroupUndo:分組撤銷eoHalfPageScroll:一次滾動半頁eoHideShowScrollBars:允許自動隱藏滾動條eoKeepCaretX:-eoNoCaret:隱藏光標eoNoSelection:禁用選擇文本eoRightMouseMovesCursor:允許鼠標右鍵移動光標eoScrollByOneLess:-eoScrollHintFollows:允許行數提示跟隨垂直滾動條eoScrollPastEof:垂直滾動條根據行數確定eoScrollPastEol:空格填充當前行eoShowScrollHint:顯示行數提示eoShowSpecialChars:允許顯示特殊字符eoSmartTabDelete:智能刪除Tab(縮進)eoSmartTabs:智能水平制表(縮進),當WantTabs為True時有效eoSpecialLineDefaultFg:-eoTabIndent:Tab和Shift+Tab縮進選擇文本(可以多行)eoTabsToSpaces:使用空格縮進,當WantTabs為True時有效eoTrimTrailingSpaces:自動去掉尾部空格
WordWrapGlyph:自動換行標記圖像設置
Glyph:自定義圖像。如果沒有使用SynEdit默認的。MaskColor:暫時不知道Visible:換行標記可見性
=================================================================================================
例子:做一個簡單的編輯器。
首先,啟動Delphi,創建個VCL項目。
然后添加SynEdit或者SynMemo(其實這兩個差不多),Align屬性為alClient。
再添加一個高亮。比如cpp的,就添加SynCppSyn。顏色、樣式(加粗,傾斜,下划線,刪除線)可以自己設置。
但是這樣是沒有任何效果的,因為SynEdit或者SynMemo的Highlighter屬性是空的。當添加SynCppSyn或者其他的高亮之后,在SynEdit或者SynMemo的Highlighter的空白處雙擊就可以了。
然后直接運行程序。輸入比如下圖的代碼。如果SynCppSyn1沒有設置顏色的話是這個效果:
選擇要修改的一項,單擊“Edit”,后面有兩個Keystroke,意思是可以使用兩個快捷鍵。

保留字是加粗的,注釋是傾斜的(Delphi編輯器的風格)。
--顯示多個高亮
這種情況在HTML居多,因為一部分人在寫HTML代碼的時候把CSS層疊樣式也寫在HTML文件里面。如果直接用一個SynHTMLSyn,CSS層疊樣式部分是不能顯示出高亮的,所以這里就需要SynMultiSyn了。
SynMultiSyn的用法和其他的高亮一樣,在SynEdit或者SynMemo設置Highlighter屬性之外,還需要至少兩個不同的高亮,比如HTML和CSS(分別是SynHTMLSyn和SynCssSyn)。
先添加SynEdit或者SynMemo,然后依次添加SynMultiSyn,SynHTMLSyn和SynCssSyn(注意和SynCsSyn區分,SynCsSyn是C#的高亮);再將SynEdit或SynMemo的Highlighter設置為SynMultiSyn1。
回到SynMultiSyn1,將DefaultHighlighter設置為SynHTMLSyn1,然后找到Schemes屬性然后單擊“...”,再單擊“Add”。其中:
把Highlighter設置為SynCssSyn1,然后設置StartExpr為“”,然后直接運行程序,編寫HTML代碼,效果如下:CaseSensitive:區分大小寫Highlighter:在StartExpr和EndExpr中間顯示的高亮EndExpr:作為Highlighter指定的高亮的結束部分MarkerAttri:標記部分顏色,字體設置SchemeName:用於區分StartExpr:作為Highlighter指定的高亮的開始部分

顏色默認設置。
如果想多個高亮也可以,一個SynMultiSyn就搞定,還是在Schemes添加,修改。
--自動換行
SynEdit和SynMemo默認是遇到#13 + #10的時候才會換行,如果打開一個文件只有一行,比如用MsXml生成的xml文件,在SynEdit或者SynMemo只顯示一行!!而且內容很多的時候看不到后面的內容。如果文件更大,程序可能會沒有響應。
在設計界面中把WordWrap改為True即可。如果不想顯示換行標記的話,把WordWrapGlyph的Visible改為False。

自動換行不影響CaretX和CaretY的值。
重要:自動換行的效率不高,打開內容較多(70KB以上)的文本文件就需要等很長時間。
此外,WordWrap和WordWrapGlyph.Visible可以通過代碼實現。
--Bookmark的添加,跳轉和清除
Bookmark的添加,跳轉已經在KeyStrokes設置好,所以就不用我們自己寫代碼了。就算是用代碼創建的SynEdit或者SynMemo也是如此。設置/取消設置的快捷鍵是Ctrl+Shift+數字,跳轉是Ctrl+數字。也可以在Keystrokes自定義快捷鍵。

當然也可以用代碼實現,主要用到以下方法:
跳轉到Bookmark:procedure TCustomSynEdit.GotoBookMark(BookMark: Integer);
清除Bookmark:procedure TCustomSynEdit.ClearBookMark(BookMark: Integer);
設置Bookmark:procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
這三個過程的BookMark都是輸入0到9的值,但實際通過Keystrokes設置還是代碼設置Bookmark 0都不起作用。其實在過程內部就判斷輸入的數是否在0..9之間,所以就不用我們if了。對於SetBookMark,第二個參數X的值和第一個一致,第三個參數Y是行號,使用CaretY就可以了。
不過,這通常和菜單一起使用,為了方便我自己寫了3個過程:
procedure TForm8.GoToBMark(BMark: Integer);
begin
SynMemo1.GotoBookMark(BMark);
end;
procedure TForm8.ToggleBMark(BMark: Integer);
begin
with SynMemo1 do
SetBookMark(BMark, BMark, CaretY);
end;
procedure TForm8.L3Click(Sender: TObject); //直接寫在菜單里的
begin
with SynMemo1 do begin
ClearBookMark(1);
ClearBookMark(2);
ClearBookMark(3);
ClearBookMark(4);
ClearBookMark(5);
ClearBookMark(6);
ClearBookMark(7);
ClearBookMark(8);
ClearBookMark(9);
end;
end;
除了清除之外,剩下的就直接調用過程即可。
--列出成員
實現這個操作,就需要另一個控件了——SynCompletionProposal。之前我已經寫了關於SynCompletionProposal的日志,可以在第三方控件系列找到。
在原來的基礎上(HTML+CSS)添加一個SynCompletionProposal,更名為ScpHTML。然后在Columns添加一個Column,接下來設置Editor屬性,設置之前的SynEdit或者SynMemo。
TriggerChars改成“<”。
EndOfTokenChr改成“<> ”。
Options屬性里面的scoUseInsertList, scoUsePrettyText, scoBuiltInTimer設置為True,其他的不改。
TimerInterval改為100或更少。
InsertList和ItemList分別輸入填充和提示文字,然后運行程序,輸入HTML代碼試試。
--Keystrokes的使用
其實在添加SynEdit或者SynMemo之后就已經設置好Keystrokes了,可以在運行時直接使用。動態創建的SynEdit或者SynMemo也可以直接使用。
一般情況下這里是不用修改的。修改很簡單,在SynEdit或者SynMemo中找到Keystrokes,然后單擊"...",如圖:

選擇要修改的一項,單擊“Edit”,后面有兩個Keystroke,意思是可以使用兩個快捷鍵。

Ctrl和Alt是不可以單獨使用的,上圖是因為截圖的時候按了Alt+PrintScreen...所以是這個結果
單擊文本框然后,按組合鍵之后單擊OK完成設置。
===================================================================================================
其實,只有上面的一些是遠遠不夠的,要實現一些高級的功能,就需要代碼實現了。
下面就是通過代碼實現的幾個實用功能:
打開與保存
打開和保存文件的方法和Memo是一樣的,使用Lines.LoadFromFile和Lines.SaveToFile就可以。只不過在Delphi 2009以后的版本保存文件的默認編碼為Unicode。使用Lines.LoadFromFile可以打開ANSI和Unicode編碼的文本文件,但打開UTF-8編碼的文本文件會亂碼。如果想支持多種編碼的文本文件,自己去寫一個過程吧。
在不同的SynHighlighter和SynCompletionProposal之間切換
設置SynEdit或者SynMemo的Highlighter屬性即可,另外,SynMultiSyn的用法和SynXXXSyn是一樣的。如果不使用任何一個:
屬性窗口:Highlighter留空;
編輯代碼:使用nil。
示例:
SynMemo1.Highlighter := SynCppSyn1; //使用C++的高亮
SynMemo1.Highlighter := nil; //不使用任何高亮
SynCompletionProposal和SynHighlighter的用法不同,SynCompletionProposal需要修改其Editor屬性,如果不需要的情況下,修改Editor屬性為nil即可。
示例:
SynCompletionProposal1.Editor := SynMemo1; //使用這個SynCompletionProposal在SynMemo1上
SynCompletionProposal1.Editor := nil; //不使用這個SynCompletionProposal在任何SynEdit或者SynMemo中
光標位置
在編寫“記事本”的時候,最頭痛的也就是光標位置了。但現在,有了SynEdit之后,就不用擔心這個問題了。SynEdit或SynMemo有兩個變量:CaretX和CaretY。在OnStatusChange把這兩個變量的值顯示出來,就知道光標的位置了。在窗體添加一個StatusBar,然后添加至少一個面板(Panel),最后在OnStatusChange中編寫代碼,搞定。
procedure TForm1.SynMemo1StatusChange(Sender: TObject;
Changes: TSynStatusChanges);
begin
StatusBar1.Panels[1].Text := IntToStr(SynMemo1.CaretX) + ': ' + IntToStr(SynMemo1.CaretY);
end;
輸入
SynEdit或SynMemo的ReadOnly屬性和Memo相同,當ReadOnly為True的時候,是不可以編輯文字的,也不能通過拖拽更改內容,而且不能剪切和粘貼。而VB在只讀(Locked)狀態下仍然可以剪切和粘貼。
用法:SynMemo1.ReadOnly := True;
SynEdit和SynMemo沒有右鍵菜單,用起來沒有Memo方便,所以我們就得自己使用一個PopupMenu了。
Modified屬性也很重要,當內容修改的時候Modified自動變為True,也可以手動修改Modified屬性為False。