📄 search.pas
字号:
unit Search;
interface
uses
Windows, Messages, SysUtils, Classes, Forms, HexEdit, NumBase, ChildFrm,
SearchTextFrm, SearchHexFrm, SearchIntFrm, SearchFloatFrm,
ReplaceTextFrm, ReplaceHexFrm;
type
{ TSearchMgr }
TSearchMgr = class(TObject)
private
FSearchKind: TSearchKind;
FSearchTextData: TSearchTextData;
FSearchHexData: TSearchHexData;
FSearchIntData: TSearchIntData;
FSearchFloatData: TSearchFloatData;
FReplaceTextData: TReplaceTextData;
FReplaceHexData: TReplaceHexData;
FResultForm: TChildForm;
procedure GetFormIdxRange(var StartIdx, EndIdx: Integer);
function GetNotFoundMsg: string;
function GetRepFromText: string;
function GetRepToText: string;
function AllowReplace: Boolean;
function HexStrToValStr(HexStr: string): string;
function Search(FromCursor: Boolean): Boolean;
procedure Replace;
public
constructor Create;
destructor Destroy; override;
function SearchFirst: Boolean;
function SearchNext: Boolean;
function ReplaceFirst: Boolean;
function ReplaceNext: Boolean;
function ReplaceAll: Boolean;
property SearchKind: TSearchKind read FSearchKind write FSearchKind;
property SearchTextData: TSearchTextData read FSearchTextData write FSearchTextData;
property SearchIntData: TSearchIntData read FSearchIntData write FSearchIntData;
property SearchHexData: TSearchHexData read FSearchHexData write FSearchHexData;
property SearchFloatData: TSearchFloatData read FSearchFloatData write FSearchFloatData;
property ReplaceTextData: TReplaceTextData read FReplaceTextData write FReplaceTextData;
property ReplaceHexData: TReplaceHexData read FReplaceHexData write FReplaceHexData;
end;
implementation
uses Misc, MainFrm;
{ TSearchMgr }
constructor TSearchMgr.Create;
begin
inherited;
end;
destructor TSearchMgr.Destroy;
begin
inherited;
end;
procedure TSearchMgr.GetFormIdxRange(var StartIdx, EndIdx: Integer);
var
AllDoc: Boolean;
begin
case FSearchKind of
skSearchText: AllDoc := FSearchTextData.AllDoc;
skSearchHex: AllDoc := FSearchHexData.AllDoc;
skSearchInt: AllDoc := FSearchIntData.AllDoc;
skSearchFloat: AllDoc := FSearchFloatData.AllDoc;
skReplaceText: AllDoc := FReplaceTextData.AllDoc;
skReplaceHex: AllDoc := FReplaceHexData.AllDoc;
else
AllDoc := False;
end;
if AllDoc then
begin
StartIdx := 0;
EndIdx := MainForm.MDIChildCount - 1;
end else
begin
StartIdx := 0;
EndIdx := 0;
end;
end;
function TSearchMgr.GetNotFoundMsg: string;
function GetFloatLen(FloatType: TFloatType): Integer;
begin
case FloatType of
ftSingle: Result := 4;
ftDouble: Result := 8;
ftReal48: Result := 6;
ftExtended: Result := 10;
else Result := 4;
end;
end;
function GetFloatHexStr(Value: Extended; FloatType: TFloatType): string;
type
PReal48 = ^Real48;
PExtended = ^Extended;
var
S: string;
I: Integer;
begin
SetLength(S, GetFloatLen(FloatType));
case FloatType of
ftSingle: PSingle(@S[1])^ := Value;
ftDouble: PDouble(@S[1])^ := Value;
ftReal48: PReal48(@S[1])^ := Value;
ftExtended: PExtended(@S[1])^ := Value;
end;
Result := '';
for I := 1 to Length(S) do
begin
if I <> 1 then Result := Result + ' ';
Result := Result + IntToHex(Ord(S[I]), 2);
end;
end;
begin
case FSearchKind of
skSearchText:
Result := '搜索文本“' + FSearchTextData.Text + '”完毕。';
skSearchHex:
Result := '搜索十六进制串“' + FSearchHexData.Text + '”完毕。';
skSearchInt:
Result := '搜索整型值“' + IntToStr(FSearchIntData.Value) + '”完毕。';
skSearchFloat:
Result := '搜索浮点值“' + FloatToStr(FSearchFloatData.Value) + '”完毕。' +
'对应十六进制串为“' + GetFloatHexStr(FSearchFloatData.Value, FSearchFloatData.Opt.FloatType) + '”。';
skReplaceText:
Result := '搜索文本“' + FReplaceTextData.FromText + '”完毕。';
skReplaceHex:
Result := '搜索十六进制串“' + FReplaceHexData.FromText + '”完毕。';
else
Result := '';
end;
end;
function TSearchMgr.GetRepFromText: string;
begin
case FSearchKind of
skReplaceText: Result := FReplaceTextData.FromText;
skReplaceHex: Result := FReplaceHexData.FromText;
else
Result := '';
end;
end;
function TSearchMgr.GetRepToText: string;
begin
case FSearchKind of
skReplaceText: Result := FReplaceTextData.ToText;
skReplaceHex: Result := FReplaceHexData.ToText;
else
Result := '';
end;
end;
function TSearchMgr.AllowReplace: Boolean;
var
R: Integer;
AskRep: Boolean;
begin
AskRep := False;
case FSearchKind of
skReplaceText:
AskRep := FReplaceTextData.AskRep;
skReplaceHex:
AskRep := FReplaceHexData.AskRep;
end;
Result := not AskRep;
if AskRep then
begin
R := MsgBox('找到一个匹配串,替换吗?', MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON1);
Result := (R = ID_YES);
end;
end;
function TSearchMgr.HexStrToValStr(HexStr: string): string;
var
I: Integer;
HexValue: Integer;
S: string;
begin
Result := '';
if Length(HexStr) mod 2 <> 0 then
Insert('0', HexStr, Length(HexStr));
for I := 0 to Length(HexStr) div 2 - 1 do
begin
S := Copy(HexStr, I*2+1, 2);
HexValue := 0;
StrToIntAsHex(HexValue, S);
Result := Result + Chr(Cardinal(HexValue));
end;
end;
function TSearchMgr.Search(FromCursor: Boolean): Boolean;
var
StartFormIdx, EndFormIdx, FormIdx: Integer;
Frm: TChildForm;
begin
Result := False;
GetFormIdxRange(StartFormIdx, EndFormIdx);
for FormIdx := StartFormIdx to EndFormIdx do
begin
if not (MainForm.MDIChildren[FormIdx] is TChildForm) then Continue;
Frm := MainForm.MDIChildren[FormIdx] as TChildForm;
case FSearchKind of
skSearchText:
begin
Frm.HexEdit.SearchTextOptions := FSearchTextData.Opt;
Result := Frm.HexEdit.SearchText(FSearchTextData.Text, FromCursor);
end;
skSearchHex:
begin
Frm.HexEdit.SearchHexOptions := FSearchHexData.Opt;
Result := Frm.HexEdit.SearchHex(FSearchHexData.Text, FromCursor);
end;
skSearchInt:
begin
Frm.HexEdit.SearchIntOptions := FSearchIntData.Opt;
Result := Frm.HexEdit.SearchInt(FSearchIntData.Value, FromCursor);
end;
skSearchFloat:
begin
Frm.HexEdit.SearchFloatOptions := FSearchFloatData.Opt;
Result := Frm.HexEdit.SearchFloat(FSearchFloatData.Value, FromCursor);
end;
skReplaceText:
begin
Frm.HexEdit.SearchTextOptions := FReplaceTextData.Opt;
Result := Frm.HexEdit.SearchText(FReplaceTextData.FromText, FromCursor);
end;
skReplaceHex:
begin
Frm.HexEdit.SearchHexOptions := FReplaceHexData.Opt;
Result := Frm.HexEdit.SearchHex(FReplaceHexData.FromText, FromCursor);
end;
end;
if Result then
begin
FResultForm := Frm;
Exit;
end;
end;
end;
procedure TSearchMgr.Replace;
begin
if not AllowReplace then Exit;
case FSearchKind of
skReplaceText:
begin
FResultForm.HexEdit.SelLength := Length(GetRepFromText);
FResultForm.HexEdit.SelData := GetRepToText;
end;
skReplaceHex:
begin
FResultForm.HexEdit.SelLength := Length(HexStrToValStr(GetRepFromText));
FResultForm.HexEdit.SelData := HexStrToValStr(GetRepToText);
end;
end;
end;
function TSearchMgr.SearchFirst: Boolean;
begin
MainForm.ShowStatusMsg('正在搜索...');
Result := Search(False);
MainForm.ShowStatusMsg('');
if Result then
begin
FResultForm.BringToFront;
end else
begin
MsgBox(GetNotFoundMsg);
end;
end;
function TSearchMgr.SearchNext: Boolean;
begin
MainForm.ShowStatusMsg('正在搜索...');
Result := Search(True);
MainForm.ShowStatusMsg('');
if Result then
begin
FResultForm.BringToFront;
end else
begin
MsgBox(GetNotFoundMsg);
end;
end;
function TSearchMgr.ReplaceFirst: Boolean;
begin
Result := Search(False);
if Result then
begin
FResultForm.BringToFront;
Replace;
end else
begin
MsgBox(GetNotFoundMsg);
end;
end;
function TSearchMgr.ReplaceNext: Boolean;
begin
Result := Search(True);
if Result then
begin
FResultForm.BringToFront;
Replace;
end else
begin
MsgBox(GetNotFoundMsg);
end;
end;
function TSearchMgr.ReplaceAll: Boolean;
begin
Result := Search(False);
while Result do
begin
FResultForm.BringToFront;
Replace;
Result := Search(True);
end;
MsgBox(GetNotFoundMsg);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -