第三方控件SynEdit
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。