📄 synedit.pas
字号:
// TCustomSynEdit events
property OnChange;
property OnClearBookmark;
property OnCommandProcessed;
property OnContextHelp;
property OnDropFiles;
property OnGutterClick;
property OnGutterGetText;
property OnGutterPaint;
property OnLineNumber;
property OnPaint;
property OnPlaceBookmark;
property OnProcessCommand;
property OnProcessUserCommand;
property OnReplaceText;
property OnScroll;
property OnSpecialLineColors;
property OnStatusChange;
property OnPaintTransient;
end;
implementation
{$R SynEdit.res}
uses
{$IFDEF SYN_CLX}
QStdActns,
QClipbrd,
QSynEditStrConst;
{$ELSE}
{$IFDEF SYN_COMPILER_4_UP}
StdActns,
{$ENDIF}
Clipbrd,
ShellAPI,
SynEditStrConst;
{$ENDIF}
{$IFDEF SYN_CLX}
const
FrameWidth = 2; { the border width when BoderStyle = bsSingle (until we support TWidgetStyle...) }
{$ENDIF}
function TrimTrailingSpaces(const S: string): string;
var
I: Integer;
begin
I := Length(S);
while (I > 0) and (S[I] in [#32,#9]) do Dec(I);
Result := Copy(S, 1, I);
end;
function Roundoff(X: Extended): Longint;
begin
if (x >= 0) then begin
Result := Trunc(x + 0.5)
end else begin
Result := Trunc(x - 0.5);
end;
end;
{ THookedCommandHandlerEntry }
type
THookedCommandHandlerEntry = class(TObject)
private
fEvent: THookedCommandEvent;
fData: pointer;
constructor Create(AEvent: THookedCommandEvent; AData: pointer);
function Equals(AEvent: THookedCommandEvent): boolean;
end;
constructor THookedCommandHandlerEntry.Create(AEvent: THookedCommandEvent;
AData: pointer);
begin
inherited Create;
fEvent := AEvent;
fData := AData;
end;
function THookedCommandHandlerEntry.Equals(AEvent: THookedCommandEvent): boolean;
begin
with TMethod(fEvent) do
Result := (Code = TMethod(AEvent).Code) and (Data = TMethod(AEvent).Data);
end;
{ TCustomSynEdit }
function TCustomSynEdit.PixelsToRowColumn(Pixels: TPoint): TPoint;
var
{$IFDEF SYN_MBCSSUPPORT}
s: string;
{$ENDIF}
f: Single;
begin
f := (Pixels.X + (fLeftChar) * fCharWidth - fGutterWidth - 2)
/ fCharWidth;
// don't return a partially visible last line
if Pixels.Y >= fLinesInWindow * fTextHeight then begin
Pixels.Y := fLinesInWindow * fTextHeight - 1;
if Pixels.Y < 0 then Pixels.Y := 0;
end;
Result := Point(Roundoff(f), Pixels.Y div fTextHeight + TopLine);
// now fix up for any TAB characters in the line
Result := PhysicalToLogicalPos(Result); // sblbg 2001-12-17
{$IFDEF SYN_MBCSSUPPORT}
if (Result.Y >= 1) and (Result.Y <= Lines.Count) then begin
s := Lines[Result.Y - 1];
if (Length(s) >= Result.x) and (ByteType(s, Result.X) = mbTrailByte) then
if Frac(f) >= 0.5 then
Dec(Result.X)
else
Inc(Result.X);
end;
{$ENDIF}
end;
function TCustomSynEdit.RowColumnToPixels(rowcol: TPoint): TPoint;
Var P :TPoint;
begin
P := LogicalToPhysicalPos(RowCol); // sblbg 2001-12-17
Result.X := (P.X-1) * fCharWidth + fTextOffset;
Result.Y := (RowCol.Y - fTopLine) * fTextHeight;
{$IFDEF SYN_CLX}
P := GetClientRect.TopLeft;
Inc( Result.X, P.X );
Inc( Result.Y, P.Y );
{$ENDIF}
end;
procedure TCustomSynEdit.ComputeCaret(X, Y: Integer);
begin
InternalCaretXY := PixelsToRowColumn(Point(X, Y));
end;
procedure TCustomSynEdit.ComputeScroll(X, Y: Integer);
var
iScrollBounds: TRect; { relative to the client area }
begin
{ don't scroll if dragging text from other control }
if (not MouseCapture) and (not Dragging) then
begin
fScrollTimer.Enabled := False;
Exit;
end;
iScrollBounds := Bounds(fGutterWidth, 0, fCharsInWindow * fCharWidth,
fLinesInWindow * fTextHeight);
if BorderStyle = bsNone then
InflateRect( iScrollBounds, -2, -2 );
if X < iScrollBounds.Left then
fScrollDeltaX := (X - iScrollBounds.Left) div fCharWidth - 1
else if X >= iScrollBounds.Right then
fScrollDeltaX := (X - iScrollBounds.Right) div fCharWidth + 1
else
fScrollDeltaX := 0;
if Y < iScrollBounds.Top then
fScrollDeltaY := (Y - iScrollBounds.Top) div fTextHeight - 1
else if Y >= iScrollBounds.Bottom then
fScrollDeltaY := (Y - iScrollBounds.Bottom) div fTextHeight + 1
else
fScrollDeltaY := 0;
fScrollTimer.Enabled := (fScrollDeltaX <> 0) or (fScrollDeltaY <> 0);
end;
procedure TCustomSynEdit.DoCopyToClipboard(const SText: string);
{$IFDEF SYN_CLX}
begin
Clipboard.AsText := SText;
end;
{$ELSE}
var
Mem: HGLOBAL;
P: PChar;
SLen: integer;
Failed: boolean;
begin
if SText <> '' then begin
Failed := TRUE; // assume the worst.
SLen := Length(SText);
// Open and Close are the only TClipboard methods we use because TClipboard
// is very hard (impossible) to work with if you want to put more than one
// format on it at a time.
Clipboard.Open;
try
// Clear anything already on the clipboard.
EmptyClipboard;
// Put it on the clipboard as normal text format so it can be pasted into
// things like notepad or Delphi.
Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, SLen + 1);
if Mem <> 0 then begin
P := GlobalLock(Mem);
try
if P <> nil then begin
Move(PChar(SText)^, P^, SLen + 1);
// Put it on the clipboard in text format
Failed := SetClipboardData(CF_TEXT, Mem) = 0;
end;
finally
GlobalUnlock(Mem);
end;
end;
// Don't free Mem! It belongs to the clipboard now, and it will free it
// when it is done with it.
if not Failed then begin
// Copy it in our custom format so we know what kind of block it is.
// That effects how it is pasted in.
Mem := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, SLen +
SizeOf(TSynSelectionMode) + 1);
P := GlobalLock(Mem);
try
if P <> nil then begin
// Our format: TSynSelectionMode value followed by text.
PSynSelectionMode(P)^ := SelectionMode;
inc(P, SizeOf(TSynSelectionMode));
Move(PChar(SText)^, P^, SLen + 1);
Failed := SetClipboardData(SynEditClipboardFormat, Mem) = 0;
end;
finally
GlobalUnlock(Mem);
end;
// Don't free Mem! It belongs to the clipboard now, and it will free it
// when it is done with it.
end;
finally
Clipboard.Close;
if Failed then
raise ESynEditError.Create('Clipboard copy operation failed');
end;
end;
end;
{$ENDIF}
procedure TCustomSynEdit.CopyToClipboard;
var
SText: string;
ChangeTrim: boolean;
begin
if SelAvail then begin
ChangeTrim := (SelectionMode = smColumn) and (eoTrimTrailingSpaces in Options);
try
if ChangeTrim then
Exclude( fOptions, eoTrimTrailingSpaces );
SText := SelText;
finally
if ChangeTrim then
Include( fOptions, eoTrimTrailingSpaces );
end;
DoCopyToClipboard(SText);
end;
end;
procedure TCustomSynEdit.CutToClipboard;
var
SText: string;
iUndoBegin, iUndoEnd: TPoint;
begin
if not ReadOnly and SelAvail then begin //jcr 2001-01-16
SText := SelText;
DoCopyToClipboard(SText);
iUndoBegin := fBlockBegin;
iUndoEnd := fBlockEnd;
LockUndo;
SelText := '';
UnlockUndo;
fUndoList.AddChange(crDelete, iUndoBegin, iUndoEnd, SText, SelectionMode);
end;
end;
constructor TCustomSynEdit.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{begin} //mh 2000-10-10
// fLines := TSynEditList.Create;
fLines := TSynEditStringList.Create;
fOrigLines := fLines;
// with TSynEditList(fLines) do begin
with TSynEditStringList(fLines) do begin
OnAdded := ListAdded;
OnChange := LinesChanged;
OnChanging := LinesChanging;
OnCleared := ListCleared;
OnDeleted := ListDeleted;
OnInserted := ListInserted;
OnPutted := ListPutted;
// OnScanRanges := ListScanRanges;
end;
{end} //mh 2000-10-10
fFontDummy := TFont.Create;
fUndoList := TSynEditUndoList.Create;
fUndoList.OnAddedUndo := UndoRedoAdded;
fOrigUndoList := fUndoList; //ddh 2002-7-15
fRedoList := TSynEditUndoList.Create;
fRedoList.OnAddedUndo := UndoRedoAdded;
fOrigRedoList := fRedoList; //ddh 2002-7-15
{$IFDEF SYN_COMPILER_4_UP}
{$IFDEF SYN_CLX}
{$ELSE}
DoubleBuffered := false;
{$ENDIF}
{$ENDIF}
fActiveLineColor := clNone;
fSelectedColor := TSynSelectedColor.Create;
fSelectedColor.OnChange := SelectedColorsChanged;
fBookMarkOpt := TSynBookMarkOpt.Create(Self);
fBookMarkOpt.OnChange := BookMarkOptionsChanged;
// fRightEdge has to be set before FontChanged is called for the first time
fRightEdge := 80;
fGutter := TSynGutter.Create;
fGutter.OnChange := GutterChanged;
fGutterWidth := fGutter.Width;
fTextOffset := fGutterWidth + 2;
{$IFDEF SYN_COMPILER_7_UP}
{$IFNDEF SYN_CLX}
ControlStyle := ControlStyle + [csOpaque, csSetCaption, csNeedsBorderPaint];
{$ELSE}
ControlStyle := ControlStyle + [csOpaque, csSetCaption];
{$ENDIF}
{$ELSE}
ControlStyle := ControlStyle + [csOpaque, csSetCaption];
{$ENDIF}
Height := 150;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -