delphi - DScintilla,代码折叠对我不起作用

标签 delphi folding scintilla

我有这段代码,用于使用 xml 词法分析器初始化 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# 或伪代码编写的代码片段

最佳答案

这里有 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;

希望这有帮助:)

关于delphi - DScintilla,代码折叠对我不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7840697/

相关文章:

intellij-idea - Intellij,项目导航。展开所有文件夹和文件树

emacs - 自动在emacs中折叠多行注释

python - 为什么我的 QsciLexerCustom 子类不能使用 QsciScintilla 在 PyQt4 中工作?

c# - 在 C#/XAML 应用程序中无法绑定(bind)到属于 WindowsFormsHost 子对象的属性的解决方法?

algorithm - 子串算法建议

Delphi-如何获取我的完整域名

delphi - 将类型声明为集合的子集

sql-server - SQL Server : Why would i add ";1" to the end of a stored procedure name?

copy-paste - 在 Visual Studio Code 中复制和粘贴折叠文本

xcode - ibtool 失败,异常 : Some Object IDs were duplicated