📄 umain.pas
字号:
unit umain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, MPHexEditor, MPHexEditorEx, ActnList, Menus, ToolWin,
ComCtrls, ImgList, ExtCtrls, ufind, uReplace, StdCtrls, IniFiles
{$IFDEF conditionalexpressions}{$IF RTLVersion >= 15}, xpman
{$IFEND}{$ENDIF};
type
TfmMain = class(TForm)
StatusBar1: TStatusBar;
MainMenu1: TMainMenu;
ActionList1: TActionList;
MPHexEditorEx1: TMPHexEditorEx;
acFileOpen: TAction;
acFileNew: TAction;
File1: TMenuItem;
New1: TMenuItem;
Open1: TMenuItem;
ImageList1: TImageList;
OpenDialog1: TOpenDialog;
CoolBar1: TCoolBar;
ToolBar1: TToolBar;
ToolButton1: TToolButton;
ToolButton2: TToolButton;
acFileSave: TAction;
Save1: TMenuItem;
ToolButton3: TToolButton;
acFileSaveAs: TAction;
SaveAs1: TMenuItem;
SaveDialog1: TSaveDialog;
N1: TMenuItem;
N2: TMenuItem;
acFileExit: TAction;
Exit1: TMenuItem;
ToolButton4: TToolButton;
acEditUndo: TAction;
ToolButton5: TToolButton;
Edit1: TMenuItem;
Undo1: TMenuItem;
acEditRedo: TAction;
ToolButton6: TToolButton;
Redo1: TMenuItem;
acEditCopy: TAction;
N3: TMenuItem;
Copy1: TMenuItem;
ToolButton7: TToolButton;
acEditCut: TAction;
Cut1: TMenuItem;
ToolButton8: TToolButton;
acEditPaste: TAction;
Paste1: TMenuItem;
ToolButton9: TToolButton;
acEditInsertNibble: TAction;
acEditDeleteNibble: TAction;
acEditSelectAll: TAction;
N4: TMenuItem;
InsertNibble1: TMenuItem;
DeleteNibble1: TMenuItem;
SelectAll1: TMenuItem;
acEditFind: TAction;
acEditFindNext: TAction;
ToolButton10: TToolButton;
ToolButton11: TToolButton;
N5: TMenuItem;
Find1: TMenuItem;
FindNext1: TMenuItem;
PopupMenu1: TPopupMenu;
Cut2: TMenuItem;
Copy2: TMenuItem;
Paste2: TMenuItem;
Undo2: TMenuItem;
Redo2: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
SelectAll2: TMenuItem;
acEditConvert: TAction;
N8: TMenuItem;
Convert1: TMenuItem;
ToolButton12: TToolButton;
acViewTranslationEditCustom: TAction;
View1: TMenuItem;
mnTranslation: TMenuItem;
EditCustomTranslation1: TMenuItem;
N9: TMenuItem;
acEditReplace: TAction;
ToolButton13: TToolButton;
Replace1: TMenuItem;
acFilePrint: TAction;
acFilePrintSetup: TAction;
ToolButton14: TToolButton;
N10: TMenuItem;
PagePreview1: TMenuItem;
Print1: TMenuItem;
PrintDialog1: TPrintDialog;
PrinterSetupDialog1: TPrinterSetupDialog;
PopupMenu2: TPopupMenu;
acViewOffsetEditFormat: TAction;
EditOffsetDisplay1: TMenuItem;
EditOffsetDisplay2: TMenuItem;
acViewOffsetHex: TAction;
acViewOffsetDec: TAction;
acViewOffsetOct: TAction;
OffsetFormat1: TMenuItem;
Hex1: TMenuItem;
Decimal1: TMenuItem;
Octal1: TMenuItem;
N11: TMenuItem;
Octal2: TMenuItem;
Decimal2: TMenuItem;
Hex2: TMenuItem;
N12: TMenuItem;
N13: TMenuItem;
N15: TMenuItem;
acViewBytesPerRow: TAction;
acViewBytesPerColumn: TAction;
BPR1: TMenuItem;
BPC1: TMenuItem;
BPR2: TMenuItem;
BPC2: TMenuItem;
acEditGoto: TAction;
N14: TMenuItem;
Goto1: TMenuItem;
acViewReadOnlyView: TAction;
N16: TMenuItem;
NoEditing1: TMenuItem;
N17: TMenuItem;
NoEditing2: TMenuItem;
acViewOptions: TAction;
ToolButton15: TToolButton;
N18: TMenuItem;
Options1: TMenuItem;
acViewBytesPerUnit: TAction;
BPU1: TMenuItem;
AboutTMPHexEditor1: TMenuItem;
acViewUnicode: TAction;
acViewUnicodeBE: TAction;
Unicode1: TMenuItem;
Unicodemode1: TMenuItem;
UnicodeBigEndian1: TMenuItem;
acViewBytesPerBlock: TAction;
BPB1: TMenuItem;
procedure acFileOpenExecute(Sender: TObject);
procedure acFileNewExecute(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure MPHexEditorEx1Progress(Sender: TObject;
const ProgressType: TMPHProgressKind; const aName: TFileName;
const Percent: Byte; var Cancel: Boolean);
procedure StatusBar1DrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
procedure acFileSaveExecute(Sender: TObject);
procedure acFileSaveAsExecute(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure acFileExitExecute(Sender: TObject);
procedure acEditUndoExecute(Sender: TObject);
procedure acEditRedoExecute(Sender: TObject);
procedure acEditCopyExecute(Sender: TObject);
procedure acEditCutExecute(Sender: TObject);
procedure acEditPasteExecute(Sender: TObject);
procedure acEditSelectAllExecute(Sender: TObject);
procedure acEditInsertNibbleExecute(Sender: TObject);
procedure acEditDeleteNibbleExecute(Sender: TObject);
procedure acEditFindExecute(Sender: TObject);
procedure acEditFindNextExecute(Sender: TObject);
procedure acEditConvertExecute(Sender: TObject);
procedure acViewTranslationEditCustomExecute(Sender: TObject);
procedure acEditReplaceExecute(Sender: TObject);
procedure acFilePrintSetupExecute(Sender: TObject);
procedure acFilePrintExecute(Sender: TObject);
procedure acViewOffsetEditFormatExecute(Sender: TObject);
procedure acViewOffsetHexExecute(Sender: TObject);
procedure acViewOffsetDecExecute(Sender: TObject);
procedure acViewOffsetOctExecute(Sender: TObject);
procedure acViewBytesPerRowExecute(Sender: TObject);
procedure acViewBytesPerColumnExecute(Sender: TObject);
procedure acEditGotoExecute(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure acViewReadOnlyViewExecute(Sender: TObject);
procedure acViewOptionsExecute(Sender: TObject);
procedure acViewBytesPerUnitExecute(Sender: TObject);
procedure AboutTMPHexEditor1Click(Sender: TObject);
procedure acViewUnicodeExecute(Sender: TObject);
procedure acViewUnicodeBEExecute(Sender: TObject);
procedure acViewBytesPerBlockExecute(Sender: TObject);
private
{ Private-Deklarationen }
// find storage
FFindRec: TFindRec;
// replace storage
FReplaceRec: TReplaceRec;
// array of known translations, built at runtime
FTranslationActions: array[TMPHTranslationKind] of TAction;
// goto amount
FGoto: string;
// storage
FIni: TMemIniFile;
// check save file
function CheckChanges: Boolean;
// do save file
function SaveFile(const ForceNewName: Boolean): Boolean;
// idle handler
procedure AppIdle(Sender: TObject; var Done: Boolean);
// translation handler
procedure TranslationExecute(Sender: TObject);
// save/restore bookmarks
procedure LoadBookmarks;
procedure SaveBookmarks;
// editor properties storage
procedure LoadEditorProps;
procedure SaveEditorProps;
public
{ Public-Deklarationen }
end;
var
fmMain: TfmMain;
implementation
uses uconvert, ucustomtranslation, uprinting, uinputnumber, uOptions;
{$R *.dfm}
// strings
const
STR_SAVECHANGES = 'Save changes to %s?';
STR_CAPTION = 'mirkes.de''s TMPHexEditor component';//'mirkes.de''s little hexer [%s]';
STR_NOT_FOUND = 'No match found.';
STR_NUM_REPLACED = '%d replacemets.';
STR_INP_BPR = 'Change Bytes per row (0=AUTO)';
STR_INP_BPC = 'Change Bytes per column';
STR_INP_BPU = 'Change Bytes per unit';
STR_INP_BPB = 'Change Bytes per block';
// status bar
STR_SB_POS = 'Pos: %s';
STR_SB_SEL = 'Sel: %s-%s';
STR_SB_SIZE = 'Size: %s';
STR_SB_MOD : array[Boolean] of Char = (' ','*');
STR_SB_RO : array[Boolean] of Char = (' ','R');
STR_SB_INS : array[Boolean] of string = ('OVW','INS');
// menu
STR_MENU_EDIT_UNDO = 'Undo: %s';
STR_MENU_EDIT_CONVERT_DATA = 'Convert Data...';
STR_MENU_EDIT_CONVERT_SEL = 'Convert Selection...';
STR_MENU_VIEW_BPR = 'Bytes Per Row: %d';
STR_MENU_VIEW_BPR_AUTO = 'Bytes Per Row: AUTO (%d)';
STR_MENU_VIEW_BPC = 'Bytes Per Column: %d';
STR_MENU_VIEW_BPU = 'Bytes Per Unit: %d';
STR_MENU_VIEW_BPB = 'Bytes Per Block: %d';
// queries
STR_QT_OFFSETPREFIX = 'Change Offset Format';
STR_Q_OFFSETPREFIX = '[r|c|Units%][-|Width!]<Base>:[Prefix]|[Suffix]';
STR_QT_GOTO = 'Goto';
STR_Q_GOTO = '[-|+|!]<Amount>';
// ini
STR_INI_BOOKMARKS = 'Bookmarks';
STR_INI_EDITOR = 'Editor';
// err->BytesPerUnit (Replace)
STR_ERR_BPU_FINDTEXT = 'Size of data to search for must be a multiple '+
'of Bytes per unit';
STR_ERR_BPU_REPLACETEXT = 'Size of replacement data must be a multiple '+
'of Bytes per unit';
procedure TfmMain.acFileOpenExecute(Sender: TObject);
begin
if CheckChanges then
begin
SaveBookmarks;
with OpenDialog1
do
if Execute
then
with MPHexEditorEx1 do
begin
try
LoadFromFile(OpenDialog1.FileName);
LoadBookmarks;
finally
StatusBar1.Panels[7].Text := '-';
end;
if ofReadOnly in Options
then
// set readonly in hexeditor if readonly was checked in dialog
// if unchecked, let the hexeditor decide if it can save the file
ReadOnlyFile := True;
end;
end;
end;
procedure TfmMain.acFileNewExecute(Sender: TObject);
begin
if CheckChanges then
begin
// create a new empty file
SaveBookmarks;
MPHexEditorEx1.CreateEmptyFile('');
end;
end;
function TfmMain.CheckChanges: Boolean;
begin
with MPHexEditorEx1 do
begin
if Modified
then
case MessageDlg(Format(STR_SAVECHANGES,[FileName]), mtConfirmation, [mbYes, mbNo, mbCancel],0) of
mrNo: Result := True;
mrYes: Result := SaveFile(False);
else
Result := False;
end
else
Result := True;
end;
end;
function TfmMain.SaveFile(const ForceNewName: Boolean): Boolean;
begin
Result := True;
with MPHexEditorEx1 do
try
if (not Modified) or (not HasFile) or (ReadOnlyFile) or ForceNewName then
begin
with SaveDialog1
do
if Execute
then
SaveToFile(FileName)
else
Result := False;
end
else
Save;
except
on E: Exception do
begin
StatusBar1.Panels[7].Text := '-';
MPHexEditorEx1.Modified := True; // saving failed, so modified again
Result := False;
Application.ShowException(E);
end;
end;
end;
procedure TfmMain.FormCreate(Sender: TObject);
var
LEnumTrans: TMPHTranslationKind;
LobjMenuItem: TMenuItem;
begin
// make sure that MYGRID is not defined in mphexeditor.pas
Assert(MPHexEditorEx1 is TCustomGrid);
// (p)reset
FFindRec.StrData := '';
FGoto := '+0x100';
FIni := TMemIniFile.Create(ChangeFileExt(ParamStr(0),'.ini'));
// create translation actions
for LEnumTrans := High(TMPHTranslationKind) downto Low(TMPHTranslationKind) do
begin
FTranslationActions[LEnumTrans] := TAction.Create(self);
with FTranslationActions[LEnumTrans] do
begin
ActionList := ActionList1;
Tag := Integer(LEnumTrans);
Caption := MPHTranslationDesc[LEnumTrans];
GroupIndex := 1;
OnExecute := TranslationExecute;
// add menuitem
LobjMenuItem := TMenuItem.Create(self);
with LobjMenuItem do
begin
RadioItem := True;
Action := FTranslationActions[LEnumTrans];
mnTranslation.Insert(0,LobjMenuItem);
end;
end;
end;
// set idle handler to update actions and status
Application.OnIdle := AppIdle;
// load editor
LoadEditorProps;
// check command line
if (ParamCount in [1,2]) and FileExists(ParamStr(1)) then
begin
with MPHexEditorEx1 do
begin
try
LoadFromFile(ParamStr(1));
LoadBookmarks;
finally
StatusBar1.Panels[7].Text := '-';
end;
end;
if ParamStr(2) = '/p' then
begin
MPHexEditorEx1.PrintOptions.Flags := MPHexEditorEx1.PrintOptions.Flags
- [pfSelectionOnly, pfCurrentViewOnly];
PrintPreview(MPHexEditorEx1, acFilePrintSetup, True);
Application.Terminate;
end;
end;
end;
procedure TfmMain.AppIdle(Sender: TObject; var Done: Boolean);
var
LEnumTrans: TMPHTranslationKind;
begin
// all actions are processed in this handler
Done := True;
with MPHexEditorEx1 do
begin
// set form caption to show filename
Caption := Format(STR_CAPTION,[FileName]);
// set statusbar
with StatusBar1 do
begin
// Position
Panels[0].Text := Format(STR_SB_POS,[Trim(GetAnyOffsetString(GetCursorPos))]);
// size
Panels[1].Text := Format(STR_SB_SIZE,[Trim(GetAnyOffsetString(DataSize))]);
// selection
if SelCount > 0
then
Panels[2].Text := Format(STR_SB_SEL,[Trim(GetAnyOffsetString(Min(SelStart, SelEnd))),
Trim(GetAnyOffsetString(Max(SelStart, SelEnd)))])
else
Panels[2].Text := '';
// changed
Panels[3].Text := STR_SB_MOD[Modified];
// readonly
Panels[4].Text := STR_SB_RO[ReadOnlyFile];
// ovw/ins
Panels[5].Text := STR_SB_INS[InsertMode];
// translation / unicode
if not UnicodeChars then
Panels[6].Text := MPHTranslationDescShort[Translation]
else
begin
if UnicodeBigEndian then
Panels[6].Text := MPH_UC_BE_S
else
Panels[6].Text := MPH_UC_S
end;
end;
// update actions - file
acFileSave.Enabled := HasFile and Modified and not (ReadOnlyView or ReadOnlyFile);
acFileSaveAs.Enabled := (not ReadOnlyView) and (DataSize > 0);
acFilePrint.Enabled := DataSize > 0;
// - edit
with acEditUndo do
begin
Enabled := CanUndo;
Caption := Format(STR_MENU_EDIT_UNDO,[UndoDescription]);
end;
acEditRedo.Enabled := CanRedo;
acEditCut.Enabled := CanCut;
acEditCopy.Enabled := CanCopy;
acEditPaste.Enabled := CanPaste;
acEditInsertNibble.Enabled := not ReadOnlyView;
acEditDeleteNibble.Enabled := (DataSize > 0) and (not ReadOnlyView);
acEditSelectAll.Enabled := DataSize > 0;
acEditFind.Enabled := DataSize > 0;
acEditFindNext.Enabled := (DataSize > 0) and (FFindRec.StrData <> '');
acEditReplace.Enabled := (DataSize > 0) and (not ReadOnlyView);
with acEditConvert do
begin
Enabled := (DataSize > 0) and (not ReadOnlyView);
if SelCount > 0
then
Caption := STR_MENU_EDIT_CONVERT_SEL
else
Caption := STR_MENU_EDIT_CONVERT_DATA
end;
// - view
// dynamic translation actions
for LEnumTrans := Low(TMPHTranslationKind) to High(TMPHTranslationKind)
do
with FTranslationActions[LEnumTrans]
do
Checked := Integer(Translation) = Tag;
acViewOffsetHex.Checked := OffsetFormat = MPHOffsetHex;
acViewOffsetDec.Checked := OffsetFormat = MPHOffsetDec;
acViewOffsetOct.Checked := OffsetFormat = MPHOffsetOct;
if AutoBytesPerRow then
acViewBytesPerRow.Caption := Format(STR_MENU_VIEW_BPR_AUTO,[BytesPerRow])
else
acViewBytesPerRow.Caption := Format(STR_MENU_VIEW_BPR,[BytesPerRow]);
acViewBytesPerColumn.Caption := Format(STR_MENU_VIEW_BPC,[BytesPerColumn]);
acViewBytesPerUnit.Caption := Format(STR_MENU_VIEW_BPU,[BytesPerUnit]);
acViewBytesPerBlock.Caption := Format(STR_MENU_VIEW_BPB,[BytesPerBlock]);
acViewBytesPerUnit.Enabled := not UnicodeChars;
mnTranslation.Enabled := not UnicodeChars;
acViewReadOnlyView.Checked := ReadOnlyView;
acViewUnicode.Checked := UnicodeChars;
if not acViewUnicode.Checked then
acViewUnicode.Enabled := ((BytesPerRow mod 2) = 0) and
((BytesPerColumn mod 2) = 0)
else
acViewUnicode.Enabled := True;
acViewUnicodeBE.Checked := UnicodeBigEndian;
acViewUnicodeBE.Enabled := UnicodeChars;
end;
end;
procedure TfmMain.MPHexEditorEx1Progress(Sender: TObject;
const ProgressType: TMPHProgressKind; const aName: TFileName;
const Percent: Byte; var Cancel: Boolean);
begin
// show progress indicator in statusbar
StatusBar1.Panels[7].Text := IntToStr(Percent);
Update;
// check esc key
Cancel := Bool(GetAsyncKeyState(VK_MENU) and (not 1));
end;
procedure TfmMain.StatusBar1DrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel; const Rect: TRect);
var
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -