下面的代码(IceMan 是原作者)对我来说很好:
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;