📄 atxreproc.pas
字号:
{$I ATViewerOptions.inc}
unit ATxREProc;
interface
uses
Windows, ComCtrls;
function RE_CurrentLine(Edit: TRichEdit): Integer;
function RE_LineFromPos(Edit: TRichEdit; Pos: Integer): Integer;
function RE_PosFromLine(Edit: TRichEdit; Line: Integer): Integer;
procedure RE_ScrollToStart(Edit: TRichEdit);
procedure RE_ScrollToEnd(Edit: TRichEdit);
procedure RE_ScrollToPos(Edit: TRichEdit; Pos, IndentVert, IndentHorz: Integer);
procedure RE_ScrollToLine(Edit: TRichEdit; Line, Indent: Integer);
procedure RE_ScrollToPercent(Edit: TRichEdit; N: Integer);
procedure RE_LoadFile(Edit: TRichEdit;
const AFileName: WideString;
ASelStart, ASelLength: Integer);
procedure RE_Print(Edit: TRichEdit;
AOnlySel: Boolean;
ACopies: Integer;
const ACaption: string);
type
TRELastSearch = record
ResultStart,
ResultLength: Integer;
SavedText: string;
SavedOptions: TSearchTypes;
end;
function RE_FindFirst(
AEdit: TRichEdit;
const AText: string;
AStartPos: Integer;
AOptions: TSearchTypes;
AIndentVert,
AIndentHorz: Integer;
var ALastSearch: TRELastSearch): Boolean;
function RE_FindNext(
AEdit: TRichEdit;
AIndentVert,
AIndentHorz: Integer;
var ALastSearch: TRELastSearch): Boolean;
implementation
uses
SysUtils, Messages, Classes,
{$ifdef TNT} TntClasses, {$endif}
Printers, RichEdit,
ATxSProc, ATxFProc, ATViewerMsg;
function RE_CurrentLine(Edit: TRichEdit): Integer;
begin
Result := Edit.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
end;
function RE_LineFromPos(Edit: TRichEdit; Pos: Integer): Integer;
begin
Result := Edit.Perform(EM_EXLINEFROMCHAR, 0, Pos);
end;
function RE_PosFromLine(Edit: TRichEdit; Line: Integer): Integer;
begin
Result := Edit.Perform(EM_LINEINDEX, Line, 0);
end;
procedure RE_HScroll(Edit: TRichEdit; HPos: Integer);
begin
Edit.Perform(WM_HSCROLL, SB_THUMBPOSITION + (HPos shl 16), 0);
end;
function RE_HPos(Edit: TRichEdit; Pos: Integer): Integer;
var
Pnt: TPoint;
begin
FillChar(Pnt, SizeOf(Pnt), 0);
Edit.Perform(EM_POSFROMCHAR, Integer(@Pnt), Pos);
Result := Pnt.X;
end;
procedure RE_ScrollToStart(Edit: TRichEdit);
var
n: DWORD;
begin
repeat
n := Edit.Perform(EM_SCROLL, SB_PAGEUP, 0);
until (n and $FFFF) = 0;
RE_HScroll(Edit, 0);
end;
procedure RE_ScrollToEnd(Edit: TRichEdit);
var
n: DWORD;
begin
repeat
n := Edit.Perform(EM_SCROLL, SB_PAGEDOWN, 0);
until (n and $FFFF) = 0;
RE_HScroll(Edit, 0);
end;
procedure RE_ScrollToPos(Edit: TRichEdit; Pos, IndentVert, IndentHorz: Integer);
var
LineNum,
LineStart,
Pos2: Integer;
begin
RE_ScrollToStart(Edit);
LineNum := RE_LineFromPos(Edit, Pos);
LineStart := RE_PosFromLine(Edit, LineNum);
Dec(LineNum, IndentVert);
if LineNum < 0 then LineNum := 0;
Edit.Perform(EM_LINESCROLL, 0, LineNum);
if RE_HPos(Edit, Pos) >= Edit.ClientWidth then
begin
Pos2 := Pos - IndentHorz;
if Pos2 < LineStart then Pos2 := LineStart;
RE_HScroll(Edit, RE_HPos(Edit, Pos2));
end;
end;
procedure RE_ScrollToLine(Edit: TRichEdit; Line, Indent: Integer);
begin
RE_ScrollToStart(Edit);
Dec(Line, Indent);
if Line < 0 then Line := 0;
Edit.Perform(EM_LINESCROLL, 0, Line);
end;
procedure RE_ScrollToPercent(Edit: TRichEdit; N: Integer);
var
Num: Integer;
begin
if N <= 0 then
begin
RE_ScrollToStart(Edit);
Edit.SelStart := 0;
Edit.SelLength := 0;
end
else
if N >= 100 then
begin
RE_ScrollToEnd(Edit);
Edit.SelStart := RE_PosFromLine(Edit, Edit.Lines.Count - 1);
Edit.SelLength := 0;
end
else
begin
Num := (Edit.Lines.Count - 1) * N div 100;
if Num > 0 then
begin
RE_ScrollToLine(Edit, Num, 0);
Edit.SelStart := RE_PosFromLine(Edit, Num);
Edit.SelLength := 0;
end;
end;
end;
procedure RE_LoadFile(Edit: TRichEdit; const AFileName: WideString; ASelStart, ASelLength: Integer);
const
Sign = #$EF#$BB#$BF;
var
IsRTF, IsUTF8: Boolean;
StreamFile, StreamData: TStream;
begin
IsFileRTFAndUTF8(AFileName, IsRTF, IsUTF8);
Edit.PlainText := not IsRTF;
with Edit do
if (Win32Platform = VER_PLATFORM_WIN32_NT) and
(not IsRTF) and (not IsUTF8) then
//Treat file as UTF8 and add missing UTF8 signature
begin
StreamFile := {$ifdef TNT}TTntFileStream{$else}TFileStream{$endif}.Create(AFileName, fmOpenRead or fmShareDenyNone);
StreamData := TMemoryStream.Create;
try
Lines.Clear;
StreamData.WriteBuffer(Sign, Length(Sign));
StreamData.CopyFrom(StreamFile, 0);
StreamData.Position := 0;
Lines.LoadFromStream(StreamData);
finally
StreamFile.Free;
StreamData.Free;
end;
end
else
//Treat file as is, RTF of UTF8 (UTF8 signature is present)
begin
StreamFile := {$ifdef TNT}TTntFileStream{$else}TFileStream{$endif}.Create(AFileName, fmOpenRead or fmShareDenyNone);
try
Lines.Clear;
Lines.LoadFromStream(StreamFile);
finally
StreamFile.Free;
end;
end;
RE_ScrollToStart(Edit);
Edit.SelStart := ASelStart;
Edit.SelLength := ASelLength;
end;
procedure RE_Print(Edit: TRichEdit;
AOnlySel: Boolean;
ACopies: Integer;
const ACaption: string);
var
ASelStart, ASelLength: Integer;
begin
if ACopies <= 0 then
ACopies := 1;
Printer.Copies := ACopies;
Printer.Canvas.Font := Edit.Font;
if AOnlySel then
begin
ASelStart := Edit.SelStart;
ASelLength := Edit.SelLength;
Edit.SelStart := ASelStart + ASelLength;
Edit.SelLength := MaxInt;
Edit.SelText := '';
Edit.SelStart := 0;
Edit.SelLength := ASelStart;
Edit.SelText := '';
end;
Edit.Print(ACaption);
end;
function RE_FindText(
AEdit: TRichEdit;
const AText: string;
AStartPos: Integer;
AOptions: TSearchTypes;
AIndentVert, AIndentHorz: Integer;
var ALastSearch: TRELastSearch): Boolean;
var
Pos: Integer;
begin
with ALastSearch do
begin
ResultStart := -1;
ResultLength := 0;
SavedText := AText;
SavedOptions := AOptions;
end;
Pos := AEdit.FindText(AText, AStartPos, MaxInt, AOptions);
Result := Pos >= 0;
if Result then
begin
ALastSearch.ResultStart := Pos;
ALastSearch.ResultLength := Length(AText);
AEdit.Lines.BeginUpdate;
AEdit.SelStart := ALastSearch.ResultStart;
AEdit.SelLength := ALastSearch.ResultLength;
RE_ScrollToPos(AEdit, ALastSearch.ResultStart, AIndentVert, AIndentHorz);
AEdit.Lines.EndUpdate;
end;
end;
function RE_FindFirst(
AEdit: TRichEdit;
const AText: string;
AStartPos: Integer;
AOptions: TSearchTypes;
AIndentVert, AIndentHorz: Integer;
var ALastSearch: TRELastSearch): Boolean;
begin
Result := RE_FindText(
AEdit,
AText,
AStartPos,
AOptions,
AIndentVert,
AIndentHorz,
ALastSearch);
end;
function RE_FindNext(
AEdit: TRichEdit;
AIndentVert, AIndentHorz: Integer;
var ALastSearch: TRELastSearch): Boolean;
begin
with ALastSearch do
begin
Assert(SavedText <> '', 'Search text is empty');
Result := RE_FindText(
AEdit,
SavedText,
ResultStart + 1,
SavedOptions,
AIndentVert,
AIndentHorz,
ALastSearch);
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -