首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SynEdit OnPaintTransientDemo

SynEdit OnPaintTransientDemo
EN

Stack Overflow用户
提问于 2013-08-28 12:12:22
回答 2查看 1.1K关注 0票数 1

我正在使用Delphi 2007SynEdit组件。

我是开源编辑器(锡-R)的主要开发人员,我正在尝试从SynEdit ANSI切换到UNICODE。

经过几个月的工作,除了OnPaintTransient程序之外,一切都很好。

为了尝试发现问题的根源,我尝试了原始的演示OnPaintTransientDemo.这在最新的ANSI版本的SynEdit中工作得很好。但是,最新的UNICODE版本并没有得到相同的结果。

如果指令只占据一行,则在光标附近只有一个符号"[] {}或()“会被错误地高亮显示,而不会关闭。

换句话说,当您单击第一个括号"(“最后一个括号")”时,“不会更改颜色。它应该给开始和结束标签上颜色。例如,将“x”作为光标的位置:

代码语言:javascript
复制
(|aaaa) -> only ( is highlighted
(aaaa|) -> only ) is highlighted

但是,如果符号都位于不同的行中,则正确地突出显示:

代码语言:javascript
复制
(|a
a
a
a) -> both () are highlighted

(a
a
a
a|) -> both () are highlighted

这看起来像是组件源中的一个bug!

(进行调试时,我找不到bug的来源。)

有人能帮忙吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-28 20:59:20

下面的代码(IceMan是原作者)对我来说很好:

代码语言:javascript
复制
procedure TForm1.EditorPaintTransient(Sender: TObject; Canvas: TCanvas; TransientType: TTransientType);
var
  Editor: TSynEdit;
  OpenChars: array of WideChar;//[0..2] of WideChar=();
  CloseChars: array of WideChar;//[0..2] of WideChar=();
  Attri: TSynHighlighterAttributes;

function IsCharBracket(AChar: WideChar): Boolean;
begin
  case AChar of
    '{',
    '[',
    '(',
    '<',
    '}',
    ']',
    ')',
    '>':
    Result:= True;
  else
    Result:= False;
  end;
end;

function CharToPixels(P: TBufferCoord): TPoint;
begin
  Result:=Editor.RowColumnToPixels(Editor.BufferToDisplayPos(P));
end;

procedure SetCanvasStyle;
begin
  Editor.Canvas.Brush.Style:= bsSolid; //Clear;
  Editor.Canvas.Font.Assign(Editor.Font);
  Editor.Canvas.Font.Style:= Attri.Style;
  if (TransientType = ttAfter) then begin
    Editor.Canvas.Font.Color:= FBracketFG;
    Editor.Canvas.Brush.Color:= FBracketBG;
  end
  else begin
    Editor.Canvas.Font.Color:= Attri.Foreground;
    Editor.Canvas.Brush.Color:= Attri.Background;
  end;

  if (Editor.Canvas.Font.Color = clNone) then
    Editor.Canvas.Font.Color:= Editor.Font.Color;
  if (Editor.Canvas.Brush.Color = clNone) then
    Editor.Canvas.Brush.Color:= Editor.Color;
end;

var
P  : TBufferCoord;
Pix: TPoint;
D  : TDisplayCoord;
S  : WideString;
I,
 ArrayLength,
 start: Integer;
TmpCharA,
 TmpCharB: WideChar;

begin
  try
    // if Memo1.InReplaceStatus = False then
    // begin
    (*
    if fMain.SyntaxHEnabled = False then exit;
    if Memo1.Highlighter = nil then exit;
    if fMain.BracketMatching = False then exit;
    if TSynEdit(Sender).SelAvail then exit;
    *)
    Editor:= TSynEdit(Sender);
    ArrayLength:= 3;
    (*
    if (Editor.Highlighter = SynHTMLSyn1) or (Editor.Highlighter = SynXMLSyn1) then
    inc(ArrayLength);
    *)
    SetLength(OpenChars,
              ArrayLength);
    SetLength(CloseChars,
              ArrayLength);

    for i:= 0 to ArrayLength - 1 do
      Case i of
        0: begin
             OpenChars[i]:= '(';
             CloseChars[i]:= ')';
           end;
        1: begin
             OpenChars[i]:= '{';
             CloseChars[i]:= '}';
           end;
        2: begin
             OpenChars[i]:= '[';
             CloseChars[i]:= ']';
           end;
        3: begin
             OpenChars[i]:= '<';
             CloseChars[i]:= '>';
           end;
      end;

    P:= Editor.CaretXY;
    D:= Editor.DisplayXY;
    Start:= Editor.SelStart;

    if (Start > 0) and
       (Start <= length(Editor.Text)) then
      TmpCharA:= Editor.Text[Start]
    else
      TmpCharA:= #0;

    if (Start < length(Editor.Text)) then
      TmpCharB:= Editor.Text[Start + 1]
    else
      TmpCharB:= #0;

    if not IsCharBracket(TmpCharA) and
       not IsCharBracket(TmpCharB) then
      Exit;

    S:= TmpCharB;
    if not IsCharBracket(TmpCharB) then begin
      P.Char:= P.Char - 1;
      S:= TmpCharA;
    end;

    Editor.GetHighlighterAttriAtRowCol(P,
                                       S,
                                       Attri);

    if (Editor.Highlighter.SymbolAttribute = Attri) then begin
      for i:= low(OpenChars) to High(OpenChars) do begin
        if (S = OpenChars[i]) or
           (S = CloseChars[i]) then begin
          Pix:= CharToPixels(P);
          SetCanvasStyle;
          Editor.Canvas.TextOut(Pix.X,
                                Pix.Y,
                                S);
          P := Editor.GetMatchingBracketEx(P);

          if (P.Char > 0) and
             (P.Line > 0) then begin
            Pix:= CharToPixels(P);
            if Pix.X > Editor.Gutter.Width then begin
              SetCanvasStyle;
              if S = OpenChars[i] then
                Editor.Canvas.TextOut(Pix.X,
                                      Pix.Y,
                                      CloseChars[i])
              else
                Editor.Canvas.TextOut(Pix.X,
                                      Pix.Y,
                                      OpenChars[i]);
            end; //if Pix.X >
          end; //if (P.Char > 0)
        end; //if (S = OpenChars[i])
      end; //for i:= low(OpenChars)
      Editor.Canvas.Brush.Style := bsSolid;
    end; //if (Editor.Highlighter.SymbolAttribute = Attri)
  except
  // TODO
  end; //try
end;
票数 1
EN

Stack Overflow用户

发布于 2021-09-17 01:11:13

CharToPixels搅乱了字体的颜色,我发现。在绘图前将font.color设置为FBrackBG似乎是可行的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18487553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档