Examples: ResExplorer

- implement a binary viewer as default viewer for resources that don't have a dedicated viewer yet.
- move the logic of what resource to view from the TreeView's OnClick to the OnSelectionChanged event.
- implement Release and Debug build modes.

git-svn-id: trunk@49568 -
This commit is contained in:
bart 2015-07-25 14:52:17 +00:00
parent f27803d409
commit 57494c5244
3 changed files with 612 additions and 13 deletions

View File

@ -21,7 +21,7 @@ object reMainForm: TreMainForm
Images = ImageList1
ReadOnly = True
TabOrder = 0
OnClick = TreeView1Click
OnSelectionChanged = TreeView1SelectionChanged
Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips]
end
object PageControl1: TPageControl
@ -29,9 +29,9 @@ object reMainForm: TreMainForm
Height = 506
Top = 56
Width = 475
ActivePage = tabString
ActivePage = tabBinary
Align = alClient
TabIndex = 0
TabIndex = 2
TabOrder = 1
object tabString: TTabSheet
Caption = 'String'
@ -67,6 +67,508 @@ object reMainForm: TreMainForm
Center = True
end
end
object tabBinary: TTabSheet
Caption = 'Binary'
ClientHeight = 478
ClientWidth = 467
inline SynEdit1: TSynEdit
Left = 0
Height = 478
Top = 0
Width = 467
Align = alClient
Font.Height = -13
Font.Name = 'Courier New'
Font.Pitch = fpFixed
Font.Quality = fqNonAntialiased
ParentColor = False
ParentFont = False
TabOrder = 0
Gutter.Width = 57
Gutter.MouseActions = <>
RightGutter.Width = 0
RightGutter.MouseActions = <>
Keystrokes = <
item
Command = ecUp
ShortCut = 38
end
item
Command = ecSelUp
ShortCut = 8230
end
item
Command = ecScrollUp
ShortCut = 16422
end
item
Command = ecDown
ShortCut = 40
end
item
Command = ecSelDown
ShortCut = 8232
end
item
Command = ecScrollDown
ShortCut = 16424
end
item
Command = ecLeft
ShortCut = 37
end
item
Command = ecSelLeft
ShortCut = 8229
end
item
Command = ecWordLeft
ShortCut = 16421
end
item
Command = ecSelWordLeft
ShortCut = 24613
end
item
Command = ecRight
ShortCut = 39
end
item
Command = ecSelRight
ShortCut = 8231
end
item
Command = ecWordRight
ShortCut = 16423
end
item
Command = ecSelWordRight
ShortCut = 24615
end
item
Command = ecPageDown
ShortCut = 34
end
item
Command = ecSelPageDown
ShortCut = 8226
end
item
Command = ecPageBottom
ShortCut = 16418
end
item
Command = ecSelPageBottom
ShortCut = 24610
end
item
Command = ecPageUp
ShortCut = 33
end
item
Command = ecSelPageUp
ShortCut = 8225
end
item
Command = ecPageTop
ShortCut = 16417
end
item
Command = ecSelPageTop
ShortCut = 24609
end
item
Command = ecLineStart
ShortCut = 36
end
item
Command = ecSelLineStart
ShortCut = 8228
end
item
Command = ecEditorTop
ShortCut = 16420
end
item
Command = ecSelEditorTop
ShortCut = 24612
end
item
Command = ecLineEnd
ShortCut = 35
end
item
Command = ecSelLineEnd
ShortCut = 8227
end
item
Command = ecEditorBottom
ShortCut = 16419
end
item
Command = ecSelEditorBottom
ShortCut = 24611
end
item
Command = ecToggleMode
ShortCut = 45
end
item
Command = ecCopy
ShortCut = 16429
end
item
Command = ecPaste
ShortCut = 8237
end
item
Command = ecDeleteChar
ShortCut = 46
end
item
Command = ecCut
ShortCut = 8238
end
item
Command = ecDeleteLastChar
ShortCut = 8
end
item
Command = ecDeleteLastChar
ShortCut = 8200
end
item
Command = ecDeleteLastWord
ShortCut = 16392
end
item
Command = ecUndo
ShortCut = 32776
end
item
Command = ecRedo
ShortCut = 40968
end
item
Command = ecLineBreak
ShortCut = 13
end
item
Command = ecSelectAll
ShortCut = 16449
end
item
Command = ecCopy
ShortCut = 16451
end
item
Command = ecBlockIndent
ShortCut = 24649
end
item
Command = ecLineBreak
ShortCut = 16461
end
item
Command = ecInsertLine
ShortCut = 16462
end
item
Command = ecDeleteWord
ShortCut = 16468
end
item
Command = ecBlockUnindent
ShortCut = 24661
end
item
Command = ecPaste
ShortCut = 16470
end
item
Command = ecCut
ShortCut = 16472
end
item
Command = ecDeleteLine
ShortCut = 16473
end
item
Command = ecDeleteEOL
ShortCut = 24665
end
item
Command = ecUndo
ShortCut = 16474
end
item
Command = ecRedo
ShortCut = 24666
end
item
Command = ecGotoMarker0
ShortCut = 16432
end
item
Command = ecGotoMarker1
ShortCut = 16433
end
item
Command = ecGotoMarker2
ShortCut = 16434
end
item
Command = ecGotoMarker3
ShortCut = 16435
end
item
Command = ecGotoMarker4
ShortCut = 16436
end
item
Command = ecGotoMarker5
ShortCut = 16437
end
item
Command = ecGotoMarker6
ShortCut = 16438
end
item
Command = ecGotoMarker7
ShortCut = 16439
end
item
Command = ecGotoMarker8
ShortCut = 16440
end
item
Command = ecGotoMarker9
ShortCut = 16441
end
item
Command = ecSetMarker0
ShortCut = 24624
end
item
Command = ecSetMarker1
ShortCut = 24625
end
item
Command = ecSetMarker2
ShortCut = 24626
end
item
Command = ecSetMarker3
ShortCut = 24627
end
item
Command = ecSetMarker4
ShortCut = 24628
end
item
Command = ecSetMarker5
ShortCut = 24629
end
item
Command = ecSetMarker6
ShortCut = 24630
end
item
Command = ecSetMarker7
ShortCut = 24631
end
item
Command = ecSetMarker8
ShortCut = 24632
end
item
Command = ecSetMarker9
ShortCut = 24633
end
item
Command = EcFoldLevel1
ShortCut = 41009
end
item
Command = EcFoldLevel2
ShortCut = 41010
end
item
Command = EcFoldLevel3
ShortCut = 41011
end
item
Command = EcFoldLevel4
ShortCut = 41012
end
item
Command = EcFoldLevel5
ShortCut = 41013
end
item
Command = EcFoldLevel6
ShortCut = 41014
end
item
Command = EcFoldLevel7
ShortCut = 41015
end
item
Command = EcFoldLevel8
ShortCut = 41016
end
item
Command = EcFoldLevel9
ShortCut = 41017
end
item
Command = EcFoldLevel0
ShortCut = 41008
end
item
Command = EcFoldCurrent
ShortCut = 41005
end
item
Command = EcUnFoldCurrent
ShortCut = 41003
end
item
Command = EcToggleMarkupWord
ShortCut = 32845
end
item
Command = ecNormalSelect
ShortCut = 24654
end
item
Command = ecColumnSelect
ShortCut = 24643
end
item
Command = ecLineSelect
ShortCut = 24652
end
item
Command = ecTab
ShortCut = 9
end
item
Command = ecShiftTab
ShortCut = 8201
end
item
Command = ecMatchBracket
ShortCut = 24642
end
item
Command = ecColSelUp
ShortCut = 40998
end
item
Command = ecColSelDown
ShortCut = 41000
end
item
Command = ecColSelLeft
ShortCut = 40997
end
item
Command = ecColSelRight
ShortCut = 40999
end
item
Command = ecColSelPageDown
ShortCut = 40994
end
item
Command = ecColSelPageBottom
ShortCut = 57378
end
item
Command = ecColSelPageUp
ShortCut = 40993
end
item
Command = ecColSelPageTop
ShortCut = 57377
end
item
Command = ecColSelLineStart
ShortCut = 40996
end
item
Command = ecColSelLineEnd
ShortCut = 40995
end
item
Command = ecColSelEditorTop
ShortCut = 57380
end
item
Command = ecColSelEditorBottom
ShortCut = 57379
end>
MouseActions = <>
MouseTextActions = <>
MouseSelActions = <>
VisibleSpecialChars = [vscSpace, vscTabAtLast]
ReadOnly = True
SelectedColor.BackPriority = 50
SelectedColor.ForePriority = 50
SelectedColor.FramePriority = 50
SelectedColor.BoldPriority = 50
SelectedColor.ItalicPriority = 50
SelectedColor.UnderlinePriority = 50
SelectedColor.StrikeOutPriority = 50
BracketHighlightStyle = sbhsBoth
BracketMatchColor.Background = clNone
BracketMatchColor.Foreground = clNone
BracketMatchColor.Style = [fsBold]
FoldedCodeColor.Background = clNone
FoldedCodeColor.Foreground = clGray
FoldedCodeColor.FrameColor = clGray
MouseLinkColor.Background = clNone
MouseLinkColor.Foreground = clBlue
LineHighlightColor.Background = clNone
LineHighlightColor.Foreground = clNone
inline SynLeftGutterPartList1: TSynGutterPartList
object SynGutterMarks1: TSynGutterMarks
Width = 24
MouseActions = <>
end
object SynGutterLineNumber1: TSynGutterLineNumber
Width = 17
MouseActions = <>
MarkupInfo.Background = clBtnFace
MarkupInfo.Foreground = clNone
DigitCount = 2
ShowOnlyLineNumbersMultiplesOf = 1
ZeroStart = False
LeadingZeros = False
end
object SynGutterChanges1: TSynGutterChanges
Width = 4
MouseActions = <>
ModifiedColor = 59900
SavedColor = clGreen
end
object SynGutterSeparator1: TSynGutterSeparator
Width = 2
MouseActions = <>
MarkupInfo.Background = clWhite
MarkupInfo.Foreground = clGray
end
object SynGutterCodeFolding1: TSynGutterCodeFolding
MouseActions = <>
MarkupInfo.Background = clNone
MarkupInfo.Foreground = clGray
MouseActionsExpanded = <>
MouseActionsCollapsed = <>
end
end
end
end
end
object Splitter1: TSplitter
Left = 288

View File

@ -5,8 +5,9 @@ unit reMainUnit;
interface
uses
SysUtils, resource, LazUTF8, Forms, Controls, Dialogs, ComCtrls, ActnList,
Menus, ExtCtrls, Grids, bitmapresource, versionresource, groupiconresource;
SysUtils, resource, LazUTF8, SynEdit, Forms, Controls, Dialogs, ComCtrls,
ActnList, Menus, ExtCtrls, Grids, bitmapresource, versionresource,
groupiconresource, Classes;
type
@ -33,6 +34,8 @@ type
Splitter1: TSplitter;
StatusBar1: TStatusBar;
StringGrid1: TStringGrid;
SynEdit1: TSynEdit;
tabBinary: TTabSheet;
tabString: TTabSheet;
tabImage: TTabSheet;
ToolBar1: TToolBar;
@ -49,13 +52,14 @@ type
Section: THeaderSection);
procedure hlpAboutExecute(Sender: TObject);
procedure Splitter1ChangeBounds(Sender: TObject);
procedure TreeView1Click(Sender: TObject);
procedure TreeView1SelectionChanged(Sender: TObject);
private
Res:TResources;
procedure ClearDisplay;
procedure LoadVersionResource(V:TVersionResource);
procedure LoadBitmapResource(B:TBitmapResource);
procedure LoadGroupIconResource(G:TGroupIconResource);
procedure LoadResourceAsBinary(R: TAbstractResource);
public
procedure OpenFile(const AFileName:string);
end;
@ -103,6 +107,8 @@ begin
OpenDialog1.Filter := sAllFilesSharedLibSoSo;
{$ENDIF}
Splitter1ChangeBounds(nil);
SynEdit1.Gutter.Visible := False;
ClearDisplay;
end;
procedure TreMainForm.FormDestroy(Sender: TObject);
@ -130,13 +136,13 @@ begin
HeaderControl1.Sections[1].Width:=Width - TreeView1.Width;
end;
procedure TreMainForm.TreeView1Click(Sender: TObject);
procedure TreMainForm.TreeView1SelectionChanged(Sender: TObject);
var
ResItem:TAbstractResource;
begin
if Assigned(TreeView1.Selected) then ClearDisplay;
if Assigned(TreeView1.Selected) and Assigned(TreeView1.Selected.Data) then
begin
ClearDisplay;
ResItem:=TAbstractResource(TreeView1.Selected.Data);
HeaderControl1.Sections[1].Text:=ResItem.ClassName + ' : ' + ResItem.Name.Name;
if ResItem is TVersionResource then
@ -148,14 +154,17 @@ begin
if ResItem is TGroupIconResource then
LoadGroupIconResource(ResItem as TGroupIconResource)
else
;
LoadResourceAsBinary(ResItem);
end;
end;
procedure TreMainForm.ClearDisplay;
begin
StringGrid1.Clean;
StringGrid1.Visible := False;
Image1.Picture.Clear;
SynEdit1.Lines.Clear;
end;
procedure TreMainForm.LoadVersionResource(V: TVersionResource);
@ -163,6 +172,7 @@ var
i,j, k:integer;
begin
PageControl1.ActivePage:=tabString;
StringGrid1.Visible := True;
k:=0;
StringGrid1.RowCount:=0;
StringGrid1.ColCount:=2;
@ -188,7 +198,59 @@ end;
procedure TreMainForm.LoadGroupIconResource(G: TGroupIconResource);
begin
//ToDo: implement proper method to display
LoadResourceAsBinary(G);
end;
procedure TreMainForm.LoadResourceAsBinary(R: TAbstractResource);
var
Offset, Size, BytesRead: Int64;
Buf: Array[0..15] of Byte;
Line, BinLine, AscLine: ShortString;
i: Integer;
begin
PageControl1.ActivePage:=tabBinary;
//writeln('TreMainForm.LoadResourceAsBinary');
//writeln(' ClassName = ',R.ClassName);
//writeln(' DataSize = ',R.DataSize);
//writeln(' R.RawData.Size = ',R.RawData.Size);
//writeln(' DataOffset = ',R.DataOffset);
//writeln(' DataVersion = ',R.DataVersion);
SynEdit1.Lines.BeginUpdate;
try
Offset := 0;
R.RawData.Position := 0;
Size := R.RawData.Size;
while (Offset < Size) do
begin
FillChar(Buf{%H-}, SizeOf(Buf), #0);
BytesRead := R.RawData.Read(Buf[0], SizeOf(Buf));
//writeln(' BytesRead = ',BytesRead);
Line := '';
BinLine := '';
Ascline := '';
for i := 0 to BytesRead - 1 do
begin
BinLine := BinLine + IntToHex(Buf[i],2) + #32;
if (Buf[i] in [32..127]) then
AscLine := AscLine + Char(Buf[i])
else
AscLine := AscLine + #32;
end;
for i := (BytesRead + 1) to SizeOf(Buf) do
begin
BinLine := BinLine + ' ';
AscLine := AscLine + ' ';
end;
Line := IntToHex(Offset, 8) + #32;
Line := Line + BinLine + #32 + AscLine + LineEnding;
//writeln(' Line = ',Line);
SynEdit1.Lines.Add(Line);
Inc(Offset, SizeOf(Buf));
end;
finally
SynEdit1.Lines.EndUpdate;
end;
end;
procedure TreMainForm.OpenFile(const AFileName: string);

View File

@ -22,8 +22,40 @@
<CharSet Value="04B0"/>
<StringTable Comments="Explore your resources in executables and resource files" CompanyName="Alexey Lagunov" FileDescription="Resource Explorer" InternalName="LazResExplorer" LegalCopyright="Alexey Lagunov" LegalTrademarks="No Trademarks" OriginalFilename="lazresexplorer" ProductName="Lazarus Resource Explorer" ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="default" Default="True"/>
<BuildModes Count="2">
<Item1 Name="Release" Default="True"/>
<Item2 Name="Debug">
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="resexplorer"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<IncludeAssertionCode Value="True"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
<UseHeaptrc Value="True"/>
<UseExternalDbgSyms Value="True"/>
</Debugging>
</Linking>
</CompilerOptions>
</Item2>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
@ -38,10 +70,13 @@
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<RequiredPackages Count="2">
<Item1>
<PackageName Value="LCL"/>
<PackageName Value="SynEdit"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="4">
<Unit0>