DScintilla,代码折叠对我不起作用
Posted
技术标签:
【中文标题】DScintilla,代码折叠对我不起作用【英文标题】:DScintilla, code folding not working for me 【发布时间】:2011-10-20 18:50:01 【问题描述】:我有这段代码,用 xml lexer 初始化 Scintilla:
procedure TfrmWeMain.DScintilla1MarginClick(ASender: TObject; AModifiers,
APosition, AMargin: Integer);
var line_number:integer;
begin
line_number:= (ASender as TDScintilla).SendEditor(SCI_LINEFROMPOSITION, APosition, 0);
case AMargin of
1:
begin
(ASender as TDScintilla).SendEditor(SCI_TOGGLEFOLD, line_number, 0);
end
end;
end;
procedure TfrmWeMain.addDocument(filename:string);
var frmEditor:tFrameEditor;
ts:TTabSheet;
procedure setColors(lang:integer;fore:integer;const back:tcolor=clWindow;
const bold:boolean=false; const italic:boolean=false;
const underline:boolean=false; const font:string='Courier New';
const size:integer=10);
begin
frmEditor.sci.StyleSetBack(lang,colortorgb(back));
frmEditor.sci.StyleSetFore(lang,colortorgb(fore));
frmEditor.sci.StyleSetFont(lang,font);
frmEditor.sci.StyleSetBold(lang,bold);
frmEditor.sci.StyleSetItalic(lang,italic);
frmEditor.sci.StyleSetUnderline(lang,underline);
frmEditor.sci.StyleSetSize(lang,size);
end;
procedure setFolding;
begin
frmEditor.sci.SetMarginTypeN(1,0);
frmEditor.sci.SetMarginTypeN(1,SC_MARGIN_SYMBOL);
frmEditor.sci.SetMarginMaskN(1,SC_MASK_FOLDERS);
frmEditor.sci.SetMarginWidthN(0,40);
frmEditor.sci.SetMarginWidthN(1,20);
frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_PLUS);
frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_MINUS);
frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_EMPTY);
frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_EMPTY);
frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_EMPTY);
frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_EMPTY);
frmEditor.sci.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY);
frmEditor.sci.SendEditor(SCI_SETFOLDFLAGS, 16, 0); // 16 Draw line below if not expanded
frmEditor.sci.OnMarginClick:=DScintilla1MarginClick;
frmeditor.sci.StartStyling(0,0);
end;
begin
///...
frmEditor.sci.SetLexer(SCLEX_XML);
frmEditor.sci.SetCodePage(CP_UTF8);
setColors(SCE_H_DEFAULT,clBlack);
setColors(SCE_H_TAG,clPurple,clWindow,true);
setColors(SCE_H_TAGUNKNOWN,clRed);
setColors(SCE_H_ATTRIBUTE,clNavy);
setColors(SCE_H_ATTRIBUTEUNKNOWN,clRed);
setColors(SCE_H_NUMBER,clBlue);
setColors(SCE_H_DOUBLESTRING,clBlue);
setColors(SCE_H_SINGLESTRING,clBlue);
setColors(SCE_H_OTHER,clBlack);
setColors(SCE_H_COMMENT,clTeal);
setColors(SCE_H_ENTITY,clPurple);
setColors(SCE_H_TAGEND,clPurple);
setColors(SCE_H_CDATA,clTeal);
setFolding;
///...
end;
查看代码的 setFolding 部分,它是折叠应该开始的地方,但它没有。我看不到折叠标记,折叠本身也不起作用。
我需要知道我在这里缺少什么,或者我做错了什么。欢迎使用 Delphi、C++、C# 或伪代码编写 sn-ps
【问题讨论】:
【参考方案1】:这里有 XML 的折叠示例。您已经很接近让它工作了,但是您错过了设置 2 个重要细节,启用全局折叠并为您的语言启用折叠(请参阅 here 了解 XML 的 fold.html 折叠属性),然后启用折叠边距对鼠标点击,实际触发 OnMarginClick 事件的原因(请参阅 here)。对于这个示例,我避免使用 SendEditor 消息传递,而是使用了 DScintilla 包装器的全部功能。
uses
DScintillaTypes;
const
MARGIN_LINE_NUMBERS = 0;
MARGIN_CODE_FOLDING = 1;
procedure TForm1.DScintilla1MarginClick(ASender: TObject; AModifiers,
APosition, AMargin: Integer);
var
Line: Integer;
begin
Line := DScintilla1.LineFromPosition(APosition);
if AMargin = MARGIN_CODE_FOLDING then
DScintilla1.ToggleFold(Line);
end;
procedure TForm1.FormCreate(Sender: TObject);
procedure SetColors(const Style: Integer; const Fore: Integer;
const Back: TColor = clWindow; const Bold: Boolean = False;
const Italic: Boolean = False; const Underline: Boolean = False;
const Font: string = 'Courier New'; const Size: Integer = 10);
begin
DScintilla1.StyleSetBack(Style, ColorToRGB(Back));
DScintilla1.StyleSetFore(Style, ColorToRGB(Fore));
DScintilla1.StyleSetFont(Style, Font);
DScintilla1.StyleSetSize(Style, Size);
DScintilla1.StyleSetBold(Style, Bold);
DScintilla1.StyleSetItalic(Style, Italic);
DScintilla1.StyleSetUnderline(Style, Underline);
end;
begin
DScintilla1.SetLexer(SCLEX_XML);
DScintilla1.SetCodePage(CP_UTF8);
// this is very important and enables the folding globally
// and then the language specific, see [1] for details
DScintilla1.SetProperty('fold', '1');
DScintilla1.SetProperty('fold.html', '1');
// I used here constant placeholders, for line numbering
// margin it's the MARGIN_LINE_NUMBERS and for code folding
// margin it's the MARGIN_CODE_FOLDING constant
DScintilla1.SetMarginWidthN(MARGIN_CODE_FOLDING, 0);
DScintilla1.SetMarginTypeN(MARGIN_CODE_FOLDING, SC_MARGIN_SYMBOL);
DScintilla1.SetMarginMaskN(MARGIN_CODE_FOLDING, SC_MASK_FOLDERS);
DScintilla1.SetMarginWidthN(MARGIN_LINE_NUMBERS, 40);
DScintilla1.SetMarginWidthN(MARGIN_CODE_FOLDING, 20);
// markers for code folding
DScintilla1.MarkerDefine(SC_MARKNUM_FOLDER, SC_MARK_PLUS);
DScintilla1.MarkerDefine(SC_MARKNUM_FOLDEROPEN, SC_MARK_MINUS);
DScintilla1.MarkerDefine(SC_MARKNUM_FOLDEREND, SC_MARK_EMPTY);
DScintilla1.MarkerDefine(SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_EMPTY);
DScintilla1.MarkerDefine(SC_MARKNUM_FOLDEROPENMID, SC_MARK_EMPTY);
DScintilla1.MarkerDefine(SC_MARKNUM_FOLDERSUB, SC_MARK_EMPTY);
DScintilla1.MarkerDefine(SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY);
// also very important, this will enable the OnMarginClick event
// to fire, if you set the ASensitive parameter to False or omit
// this line, the OnMarginClick will never fire
DScintilla1.SetMarginSensitiveN(MARGIN_CODE_FOLDING, True);
// and some visual settings
SetColors(SCE_H_DEFAULT, clBlack);
SetColors(SCE_H_TAG, clPurple, clWindow, True);
SetColors(SCE_H_TAGUNKNOWN, clRed);
SetColors(SCE_H_ATTRIBUTE, clNavy);
SetColors(SCE_H_ATTRIBUTEUNKNOWN, clRed);
SetColors(SCE_H_NUMBER, clBlue);
SetColors(SCE_H_DOUBLESTRING, clBlue);
SetColors(SCE_H_SINGLESTRING, clBlue);
SetColors(SCE_H_OTHER, clBlack);
SetColors(SCE_H_COMMENT, clTeal);
SetColors(SCE_H_ENTITY, clPurple);
SetColors(SCE_H_TAGEND, clPurple);
SetColors(SCE_H_CDATA, clTeal);
end;
希望这会有所帮助:)
【讨论】:
谢谢,我下午试试,结果回来以上是关于DScintilla,代码折叠对我不起作用的主要内容,如果未能解决你的问题,请参考以下文章