fpspreadsheet: Improvements for BIFFExplorer (use KHexEditor, simplify virtual tree node management, fix memory leaks).

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4513 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-02-21 10:50:54 +00:00
parent d2b80cf143
commit b0adfe7a2a
8 changed files with 558 additions and 509 deletions

View File

@ -100,19 +100,22 @@
<FormatVersion Value="1"/> <FormatVersion Value="1"/>
</local> </local>
</RunParams> </RunParams>
<RequiredPackages Count="4"> <RequiredPackages Count="5">
<Item1> <Item1>
<PackageName Value="laz_fpspreadsheet"/> <PackageName Value="KControlsLaz"/>
</Item1> </Item1>
<Item2> <Item2>
<PackageName Value="TurboPowerIPro"/> <PackageName Value="laz_fpspreadsheet"/>
</Item2> </Item2>
<Item3> <Item3>
<PackageName Value="virtualtreeview_package"/> <PackageName Value="TurboPowerIPro"/>
</Item3> </Item3>
<Item4> <Item4>
<PackageName Value="LCL"/> <PackageName Value="virtualtreeview_package"/>
</Item4> </Item4>
<Item5>
<PackageName Value="LCL"/>
</Item5>
</RequiredPackages> </RequiredPackages>
<Units Count="11"> <Units Count="11">
<Unit0> <Unit0>

View File

@ -7,8 +7,8 @@ uses
cthreads, cthreads,
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset Interfaces, // this includes the LCL widgetset
Forms, virtualtreeview_package, laz_fpspreadsheet, beabout, bebiffgrid, Forms, virtualtreeview_package, laz_fpspreadsheet, kcontrolslaz, beabout,
bebiffutils, behtml, beutils, mrumanager, beMain, beTypes; bebiffgrid, bebiffutils, behtml, beutils, mrumanager, beMain, beTypes;
{$R *.res} {$R *.res}

View File

@ -9,7 +9,7 @@ object AboutForm: TAboutForm
Color = clWindow Color = clWindow
OnCreate = FormCreate OnCreate = FormCreate
Position = poMainFormCenter Position = poMainFormCenter
LCLVersion = '1.3' LCLVersion = '1.7'
object Panel1: TPanel object Panel1: TPanel
Left = 0 Left = 0
Height = 66 Height = 66

View File

@ -66,6 +66,10 @@ begin
'fpspreadsheet', 'fpspreadsheet',
'http://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fpspreadsheet/') 'http://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fpspreadsheet/')
); );
AddListItem(Hyperlink(
'KControls',
'http://www.tkweb.eu/en/delphicomp/kcontrols.html')
);
EndBulletList; EndBulletList;
AddEmptyLine; AddEmptyLine;

View File

@ -152,10 +152,13 @@ type
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure SetBIFFNodeData(AData: TBIFFNodeData; ABuffer: TBIFFBuffer; AFormat: TsSpreadsheetFormat); procedure SetBIFFNodeData(AData: PBIFFNodeData; ABuffer: TBIFFBuffer;
AFormat: TsSpreadsheetFormat);
published published
property TabOrder;
property OnDetails: TBIFFDetailsEvent read FOnDetails write FOnDetails; property OnDetails: TBIFFDetailsEvent read FOnDetails write FOnDetails;
property OnSelection;
end; end;
implementation implementation
@ -579,14 +582,14 @@ begin
end; end;
procedure TBIFFGrid.SetBIFFNodeData(AData: TBIFFNodeData; procedure TBIFFGrid.SetBIFFNodeData(AData: PBIFFNodeData;
ABuffer: TBIFFBuffer; AFormat: TsSpreadsheetFormat); ABuffer: TBIFFBuffer; AFormat: TsSpreadsheetFormat);
begin begin
if AData = nil then if AData = nil then
exit; exit;
FFormat := AFormat; FFormat := AFormat;
FRecType := AData.RecordID; FRecType := AData^.RecordID;
FInfo := AData.Tag; FInfo := AData^.Tag;
SetLength(FBuffer, Length(ABuffer)); SetLength(FBuffer, Length(ABuffer));
if Length(FBuffer) > 0 then if Length(FBuffer) > 0 then
Move(ABuffer[0], FBuffer[0], Length(FBuffer)); Move(ABuffer[0], FBuffer[0], Length(FBuffer));
@ -2358,13 +2361,18 @@ var
s: String; s: String;
begin begin
RowCount := FixedRows + 1; RowCount := FixedRows + 1;
ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8, if Length(FBuffer) = 0 then
s, numbytes); ShowInRow(FCurrRow, FBufferIndex, 0, '', '(empty record)')
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, else
'Page footer string' + IfThen(FFormat = sfExcel8, begin
' (Unicode string, 16-bit string length)', ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8,
' (byte string, 8-bit string length)' s, numbytes);
)); ShowInRow(FCurrRow, FBufferIndex, numbytes, s,
'Page footer string' + IfThen(FFormat = sfExcel8,
' (Unicode string, 16-bit string length)',
' (byte string, 8-bit string length)'
));
end;
end; end;
@ -2999,13 +3007,18 @@ var
s: String; s: String;
begin begin
RowCount := FixedRows + 1; RowCount := FixedRows + 1;
ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8, if Length(FBuffer) = 0 then
s, numbytes); ShowInRow(FCurrRow, FBufferIndex, 0, '', '(empty record)')
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, else
'Page header string' + IfThen(FFormat = sfExcel8, begin
' (Unicode string, 16-bit string length)', ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8,
' (byte string, 8-bit string length)' s, numbytes);
)); ShowInRow(FCurrRow, FBufferIndex, numbytes, s,
'Page header string' + IfThen(FFormat = sfExcel8,
' (Unicode string, 16-bit string length)',
' (byte string, 8-bit string length)'
));
end;
end; end;

View File

@ -17,13 +17,13 @@ object MainForm: TMainForm
LCLVersion = '1.7' LCLVersion = '1.7'
object Splitter1: TSplitter object Splitter1: TSplitter
Left = 419 Left = 419
Height = 506 Height = 508
Top = 27 Top = 25
Width = 5 Width = 5
end end
object ToolBar: TToolBar object ToolBar: TToolBar
Left = 4 Left = 4
Height = 27 Height = 25
Top = 0 Top = 0
Width = 1085 Width = 1085
AutoSize = True AutoSize = True
@ -35,25 +35,25 @@ object MainForm: TMainForm
TabOrder = 1 TabOrder = 1
object ToolButton1: TToolButton object ToolButton1: TToolButton
Left = 1 Left = 1
Top = 2 Top = 0
Action = AcFileOpen Action = AcFileOpen
DropdownMenu = RecentFilesPopupMenu DropdownMenu = RecentFilesPopupMenu
Style = tbsDropDown Style = tbsDropDown
end end
object ToolButton2: TToolButton object ToolButton2: TToolButton
Left = 64 Left = 64
Top = 2 Top = 0
Action = AcFileQuit Action = AcFileQuit
end end
object ToolButton3: TToolButton object ToolButton3: TToolButton
Left = 36 Left = 36
Top = 2 Top = 0
Action = AcFind Action = AcFind
end end
object ToolButton4: TToolButton object ToolButton4: TToolButton
Left = 59 Left = 59
Height = 25 Height = 25
Top = 2 Top = 0
Width = 5 Width = 5
Caption = 'ToolButton4' Caption = 'ToolButton4'
Style = tbsDivider Style = tbsDivider
@ -61,32 +61,32 @@ object MainForm: TMainForm
end end
object DetailPanel: TPanel object DetailPanel: TPanel
Left = 424 Left = 424
Height = 506 Height = 508
Top = 27 Top = 25
Width = 665 Width = 665
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 506 ClientHeight = 508
ClientWidth = 665 ClientWidth = 665
TabOrder = 2 TabOrder = 3
object PageControl: TPageControl object PageControl: TPageControl
Left = 0 Left = 0
Height = 506 Height = 508
Top = 0 Top = 0
Width = 665 Width = 665
ActivePage = PgAnalysis ActivePage = PgValues
Align = alClient Align = alClient
TabIndex = 0 TabIndex = 1
TabOrder = 0 TabOrder = 0
OnChange = PageControlChange OnChange = PageControlChange
object PgAnalysis: TTabSheet object PgAnalysis: TTabSheet
Caption = 'Analysis' Caption = 'Analysis'
ClientHeight = 478 ClientHeight = 480
ClientWidth = 657 ClientWidth = 657
object AnalysisDetails: TMemo object AnalysisDetails: TMemo
Left = 0 Left = 0
Height = 191 Height = 191
Top = 287 Top = 289
Width = 657 Width = 657
Align = alBottom Align = alBottom
Font.CharSet = ANSI_CHARSET Font.CharSet = ANSI_CHARSET
@ -103,7 +103,7 @@ object MainForm: TMainForm
Cursor = crVSplit Cursor = crVSplit
Left = 0 Left = 0
Height = 5 Height = 5
Top = 282 Top = 284
Width = 657 Width = 657
Align = alBottom Align = alBottom
ResizeAnchor = akBottom ResizeAnchor = akBottom
@ -111,12 +111,12 @@ object MainForm: TMainForm
end end
object PgValues: TTabSheet object PgValues: TTabSheet
Caption = 'Values' Caption = 'Values'
ClientHeight = 478 ClientHeight = 480
ClientWidth = 657 ClientWidth = 657
object ValueGrid: TStringGrid object ValueGrid: TStringGrid
Left = 0 Left = 0
Height = 158 Height = 158
Top = 320 Top = 322
Width = 657 Width = 657
Align = alBottom Align = alBottom
ColCount = 3 ColCount = 3
@ -125,8 +125,9 @@ object MainForm: TMainForm
MouseWheelOption = mwGrid MouseWheelOption = mwGrid
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goColSizing, goThumbTracking, goSmoothScroll] Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goColSizing, goThumbTracking, goSmoothScroll]
RowCount = 9 RowCount = 9
TabOrder = 0 TabOrder = 3
TitleStyle = tsNative TitleStyle = tsNative
OnClick = ValueGridClick
OnPrepareCanvas = ValueGridPrepareCanvas OnPrepareCanvas = ValueGridPrepareCanvas
ColWidths = ( ColWidths = (
112 112
@ -146,238 +147,119 @@ object MainForm: TMainForm
'Offset range' 'Offset range'
) )
end end
object HexPanel: TPanel
Left = 0
Height = 315
Top = 0
Width = 657
Align = alClient
Caption = 'HexPanel'
ClientHeight = 315
ClientWidth = 657
TabOrder = 1
object HexGrid: TStringGrid
Left = 1
Height = 313
Top = 1
Width = 373
Align = alClient
AutoFillColumns = True
ColCount = 17
DefaultColWidth = 28
ExtendedSelect = False
MouseWheelOption = mwGrid
Options = [goFixedVertLine, goFixedHorzLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goThumbTracking, goSmoothScroll]
ParentFont = False
TabOrder = 0
TitleStyle = tsNative
OnClick = GridClick
OnPrepareCanvas = HexGridPrepareCanvas
OnSelection = HexGridSelection
ColWidths = (
28
20
20
20
20
20
20
20
20
20
20
20
20
20
20
20
24
)
Cells = (
16
1
0
'0'
2
0
'1'
3
0
'2'
4
0
'3'
5
0
'4'
6
0
'5'
7
0
'6'
8
0
'7'
9
0
'8'
10
0
'9'
11
0
'10'
12
0
'11'
13
0
'12'
14
0
'13'
15
0
'14'
16
0
'15'
)
end
object AlphaGrid: TStringGrid
Left = 379
Height = 313
Top = 1
Width = 277
Align = alRight
AutoFillColumns = True
ColCount = 16
FixedCols = 0
MouseWheelOption = mwGrid
Options = [goFixedVertLine, goFixedHorzLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goThumbTracking, goSmoothScroll]
ParentFont = False
TabOrder = 1
TitleStyle = tsNative
OnClick = GridClick
OnSelection = AlphaGridSelection
ColWidths = (
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
)
Cells = (
16
0
0
'0'
1
0
'1'
2
0
'2'
3
0
'3'
4
0
'4'
5
0
'5'
6
0
'6'
7
0
'7'
8
0
'8'
9
0
'9'
10
0
'A'
11
0
'B'
12
0
'C'
13
0
'D'
14
0
'E'
15
0
'F'
)
end
object HexDumpSplitter: TSplitter
Left = 374
Height = 313
Top = 1
Width = 5
Align = alRight
ResizeAnchor = akRight
end
end
object HexSplitter: TSplitter object HexSplitter: TSplitter
Cursor = crVSplit Cursor = crVSplit
Left = 0 Left = 0
Height = 5 Height = 5
Top = 315 Top = 317
Width = 657 Width = 657
Align = alBottom Align = alBottom
ResizeAnchor = akBottom ResizeAnchor = akBottom
end end
object HexEditor: TKHexEditor
Left = 0
Height = 286
Top = 31
Width = 657
AddressPrefix = '$'
Align = alClient
Colors.HorzLines = clBlack
Colors.InactiveCaretBkGnd = clGrayText
Colors.InactiveCaretSelBkGnd = clGrayText
Colors.InactiveCaretSelText = clHighlightText
Colors.InactiveCaretText = clHighlightText
Colors.Separators = clBtnFace
Colors.VertLines = clScrollBar
DigitGrouping = 1
DisabledDrawStyle = eddNormal
Font.Height = -13
Font.Name = 'Courier New'
Font.Pitch = fpFixed
Font.Style = [fsBold]
LineHeightPercent = 120
ReadOnly = True
TabOrder = 1
OnClick = HexEditorClick
OnKeyDown = HexEditorKeyDown
end
object HexEditorParamsPanel: TPanel
Left = 0
Height = 31
Top = 0
Width = 657
Align = alTop
BevelOuter = bvNone
ClientHeight = 31
ClientWidth = 657
TabOrder = 0
object CbHexAddress: TCheckBox
Left = 3
Height = 19
Top = 5
Width = 131
Caption = 'Hexadecimal address'
Checked = True
OnChange = CbHexAddressChange
State = cbChecked
TabOrder = 0
end
object CbHexEditorLineSize: TComboBox
Left = 152
Height = 23
Top = 3
Width = 121
ItemHeight = 15
ItemIndex = 0
Items.Strings = (
'normal lines'
'long lines'
)
OnChange = CbHexEditorLineSizeChange
Style = csDropDownList
TabOrder = 1
Text = 'normal lines'
end
object CbHexSingleBytes: TCheckBox
Left = 296
Height = 19
Top = 5
Width = 83
Caption = 'Single bytes'
Checked = True
OnChange = CbHexSingleBytesChange
State = cbChecked
TabOrder = 2
end
end
end end
end end
end end
object TreePanel: TPanel object TreePanel: TPanel
Left = 0 Left = 0
Height = 506 Height = 508
Top = 27 Top = 25
Width = 419 Width = 419
Align = alLeft Align = alLeft
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 506 ClientHeight = 508
ClientWidth = 419 ClientWidth = 419
Constraints.MinWidth = 275 Constraints.MinWidth = 275
TabOrder = 3 TabOrder = 2
object FindPanel: TPanel object FindPanel: TPanel
Left = 0 Left = 0
Height = 36 Height = 30
Top = 470 Top = 478
Width = 419 Width = 419
Align = alBottom Align = alBottom
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 36 ClientHeight = 30
ClientWidth = 419 ClientWidth = 419
TabOrder = 0 TabOrder = 1
Visible = False Visible = False
object BtnFindNext: TSpeedButton object BtnFindNext: TSpeedButton
Left = 240 Left = 240
Height = 22 Height = 22
Top = 6 Top = 3
Width = 23 Width = 23
Action = AcFindNext Action = AcFindNext
Flat = True Flat = True
@ -385,7 +267,7 @@ object MainForm: TMainForm
object BtnFindPrev: TSpeedButton object BtnFindPrev: TSpeedButton
Left = 216 Left = 216
Height = 22 Height = 22
Top = 6 Top = 3
Width = 23 Width = 23
Action = AcFindPrev Action = AcFindPrev
Flat = True Flat = True
@ -393,7 +275,7 @@ object MainForm: TMainForm
object SpeedButton3: TSpeedButton object SpeedButton3: TSpeedButton
Left = 3 Left = 3
Height = 22 Height = 22
Top = 6 Top = 3
Width = 23 Width = 23
Action = AcFindClose Action = AcFindClose
Flat = True Flat = True
@ -401,7 +283,7 @@ object MainForm: TMainForm
object CbFind: TComboBox object CbFind: TComboBox
Left = 28 Left = 28
Height = 23 Height = 23
Top = 5 Top = 3
Width = 183 Width = 183
ItemHeight = 15 ItemHeight = 15
OnChange = CbFindChange OnChange = CbFindChange
@ -411,7 +293,7 @@ object MainForm: TMainForm
end end
object BIFFTree: TVirtualStringTree object BIFFTree: TVirtualStringTree
Left = 0 Left = 0
Height = 470 Height = 478
Top = 0 Top = 0
Width = 419 Width = 419
Align = alClient Align = alClient
@ -459,7 +341,7 @@ object MainForm: TMainForm
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible] Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible]
HintMode = hmTooltip HintMode = hmTooltip
PopupMenu = TreePopupMenu PopupMenu = TreePopupMenu
TabOrder = 1 TabOrder = 0
TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoSpanColumns, toAutoTristateTracking, toAutoDeleteMovedNodes] TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoSpanColumns, toAutoTristateTracking, toAutoDeleteMovedNodes]
TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowRoot, toThemeAware, toUseBlendedImages] TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowRoot, toThemeAware, toUseBlendedImages]
TreeOptions.SelectionOptions = [toFullRowSelect] TreeOptions.SelectionOptions = [toFullRowSelect]

File diff suppressed because it is too large Load Diff

View File

@ -14,26 +14,17 @@ const
type type
{ Virtual tree node data } { Virtual tree node data }
TBiffNodeData = class TBiffNodeData = record //class
Offset: Integer; Offset: Integer;
RecordID: Integer; RecordID: Integer;
RecordName: String; RecordName: String;
RecordDescription: String; RecordDescription: String;
Index: Integer; Index: Integer;
Tag: Integer; Tag: Integer;
destructor Destroy; override;
end; end;
PBiffNodeData = ^TBiffNodeData;
implementation implementation
{ TBiffNodeData }
destructor TBiffNodeData.Destroy;
begin
Finalize(RecordName);
Finalize(RecordDescription);
inherited;
end;
end. end.