You've already forked lazarus-ccr
fpspreadsheet: Add more details on DEFINEDNAME record to BIFFExplorer; add details on EXTERN* records; fix compilation issue with TIpHTMLPanel.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3483 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -65,21 +65,4 @@ object AboutForm: TAboutForm
|
|||||||
Align = alTop
|
Align = alTop
|
||||||
Shape = bsTopLine
|
Shape = bsTopLine
|
||||||
end
|
end
|
||||||
object HTMLViewer: TIpHtmlPanel
|
|
||||||
Left = 0
|
|
||||||
Height = 440
|
|
||||||
Top = 72
|
|
||||||
Width = 642
|
|
||||||
Align = alClient
|
|
||||||
FixedTypeface = 'Courier New'
|
|
||||||
DefaultTypeFace = 'default'
|
|
||||||
DefaultFontSize = 9
|
|
||||||
FlagErrors = False
|
|
||||||
PrintSettings.MarginLeft = 0.5
|
|
||||||
PrintSettings.MarginTop = 0.5
|
|
||||||
PrintSettings.MarginRight = 0.5
|
|
||||||
PrintSettings.MarginBottom = 0.5
|
|
||||||
TabOrder = 1
|
|
||||||
OnHotClick = HTMLViewerHotClick
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
@ -16,13 +16,13 @@ type
|
|||||||
Bevel1: TBevel;
|
Bevel1: TBevel;
|
||||||
BtnClose: TButton;
|
BtnClose: TButton;
|
||||||
IconImage: TImage;
|
IconImage: TImage;
|
||||||
HTMLViewer: TIpHtmlPanel;
|
|
||||||
LblTitle: TLabel;
|
LblTitle: TLabel;
|
||||||
Panel1: TPanel;
|
Panel1: TPanel;
|
||||||
procedure FormCreate(Sender: TObject);
|
procedure FormCreate(Sender: TObject);
|
||||||
procedure HTMLViewerHotClick(Sender: TObject);
|
procedure HTMLViewerHotClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
{ private declarations }
|
{ private declarations }
|
||||||
|
FHTMLViewer: TIpHtmlPanel;
|
||||||
function CreateCredits: String;
|
function CreateCredits: String;
|
||||||
public
|
public
|
||||||
{ public declarations }
|
{ public declarations }
|
||||||
@ -101,6 +101,8 @@ begin
|
|||||||
));
|
));
|
||||||
EndBulletList;
|
EndBulletList;
|
||||||
|
|
||||||
|
AddEmptyLine;
|
||||||
|
|
||||||
EndDocument;
|
EndDocument;
|
||||||
|
|
||||||
Result := Lines.Text;
|
Result := Lines.Text;
|
||||||
@ -127,13 +129,19 @@ begin
|
|||||||
ico.Free;
|
ico.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
HTMLViewer.SetHTMLFromStr(CreateCredits);
|
FHTMLViewer := TIpHtmlPanel.Create(self);
|
||||||
|
FHTMLViewer.Parent := self;
|
||||||
|
FHTMLViewer.Align := alClient;
|
||||||
|
FHTMLViewer.DefaultFontSize := 9;
|
||||||
|
FHTMLViewer.OnHotClick := @HTMLViewerHotClick;
|
||||||
|
|
||||||
|
FHTMLViewer.SetHTMLFromStr(CreateCredits);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TAboutForm.HTMLViewerHotClick(Sender: TObject);
|
procedure TAboutForm.HTMLViewerHotClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
OpenURL(HTMLViewer.HotURL);
|
OpenURL((Sender as TIpHtmlPanel).HotURL);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ type
|
|||||||
procedure ShowBottomMargin;
|
procedure ShowBottomMargin;
|
||||||
procedure ShowCalcCount;
|
procedure ShowCalcCount;
|
||||||
procedure ShowCalcMode;
|
procedure ShowCalcMode;
|
||||||
|
procedure ShowCellAddress;
|
||||||
|
procedure ShowCellAddressRange;
|
||||||
procedure ShowClrtClient;
|
procedure ShowClrtClient;
|
||||||
procedure ShowCodePage;
|
procedure ShowCodePage;
|
||||||
procedure ShowColInfo;
|
procedure ShowColInfo;
|
||||||
@ -45,6 +47,9 @@ type
|
|||||||
procedure ShowDSF;
|
procedure ShowDSF;
|
||||||
procedure ShowEOF;
|
procedure ShowEOF;
|
||||||
procedure ShowExcel9File;
|
procedure ShowExcel9File;
|
||||||
|
procedure ShowExternalBook;
|
||||||
|
procedure ShowExternCount;
|
||||||
|
procedure ShowExternSheet;
|
||||||
procedure ShowFileSharing;
|
procedure ShowFileSharing;
|
||||||
procedure ShowFnGroupCount;
|
procedure ShowFnGroupCount;
|
||||||
procedure ShowFont;
|
procedure ShowFont;
|
||||||
@ -128,6 +133,9 @@ uses
|
|||||||
fpsutils,
|
fpsutils,
|
||||||
beBIFFUtils;
|
beBIFFUtils;
|
||||||
|
|
||||||
|
const
|
||||||
|
ABS_REL: array[boolean] of string = ('abs', 'rel');
|
||||||
|
|
||||||
constructor TBIFFGrid.Create(AOwner: TComponent);
|
constructor TBIFFGrid.Create(AOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
@ -270,6 +278,10 @@ begin
|
|||||||
ShowHeader;
|
ShowHeader;
|
||||||
$0015:
|
$0015:
|
||||||
ShowFooter;
|
ShowFooter;
|
||||||
|
$0016:
|
||||||
|
ShowExternCount;
|
||||||
|
$0017:
|
||||||
|
ShowExternSheet;
|
||||||
$0018, $0218:
|
$0018, $0218:
|
||||||
ShowDefinedName;
|
ShowDefinedName;
|
||||||
$0019:
|
$0019:
|
||||||
@ -370,6 +382,8 @@ begin
|
|||||||
ShowTabID;
|
ShowTabID;
|
||||||
$0161:
|
$0161:
|
||||||
ShowDSF;
|
ShowDSF;
|
||||||
|
$01AE:
|
||||||
|
ShowExternalBook;
|
||||||
$01AF:
|
$01AF:
|
||||||
ShowProt4Rev;
|
ShowProt4Rev;
|
||||||
$01B7:
|
$01B7:
|
||||||
@ -683,6 +697,186 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBIFFGrid.ShowCellAddress;
|
||||||
|
var
|
||||||
|
numBytes: Word;
|
||||||
|
b: Byte;
|
||||||
|
w: Word;
|
||||||
|
r,c: Integer;
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes); // row --> w
|
||||||
|
r := WordLEToN(w);
|
||||||
|
if FFormat = sfExcel8 then begin
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex+2], w, numBytes); // column --w1
|
||||||
|
c := WordLEToN(w);
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('RowIndex information:'#13);
|
||||||
|
FDetails.Add(Format('RowIndex = %d (%s)', [r, ABS_REL[c and $4000 <> 0]]));
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [r, r]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Row index');
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('ColIndex information:'#13);
|
||||||
|
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c and $3FFF, ABS_REL[c and $8000 <> 0]]));
|
||||||
|
if c and $4000 = 0
|
||||||
|
then FDetails.Add('Bit 14=0: absolute row index')
|
||||||
|
else FDetails.Add('Bit 14=1: relative row index');
|
||||||
|
if c and $8000 = 0
|
||||||
|
then FDetails.Add('Bit 15=0: absolute column index')
|
||||||
|
else FDetails.Add('Bit 15=1: relative column index');
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [c, c]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Column index');
|
||||||
|
end else begin
|
||||||
|
numbytes := 1;
|
||||||
|
Move(FBuffer[FBufferIndex+2], b, numBytes);
|
||||||
|
c := b;
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('RowIndex information:'#13);
|
||||||
|
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r and $3FFF, ABS_REL[r and $4000 <> 0]]));
|
||||||
|
if r and $4000 = 0
|
||||||
|
then FDetails.Add('Bit 14=0: absolute row index')
|
||||||
|
else FDetails.Add('Bit 14=1: relative row index');
|
||||||
|
if r and $8000 = 0
|
||||||
|
then FDetails.Add('Bit 15=0: absolute column index')
|
||||||
|
else FDetails.Add('Bit 15=1: relative column index');
|
||||||
|
end;
|
||||||
|
//s := Format('$%.4x (%d, %s)', [r, r and $3FFF, ABS_REL[r and $4000 <> 0]]);
|
||||||
|
s := Format('%d ($%.4x)', [r, r]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Row index');
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('ColIndex information:'#13);
|
||||||
|
FDetails.Add(Format('ColIndex = %d (%s)', [c, ABS_REL[r and $8000 <> 0]]));
|
||||||
|
end;
|
||||||
|
//s := Format('$%.2x (%d, %s)', [c, c, ABS_REL[r and $8000 <> 0]]);
|
||||||
|
s := Format('%d ($%.4x)', [c, c]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Column index');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBIFFGrid.ShowCellAddressRange;
|
||||||
|
var
|
||||||
|
numbytes: Word;
|
||||||
|
b: Byte;
|
||||||
|
w: Word;
|
||||||
|
r, c, r2, c2: Integer;
|
||||||
|
s: String;
|
||||||
|
begin
|
||||||
|
if FFormat = sfExcel8 then begin
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
r := WordLEToN(w);
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('RowIndex information:'#13);
|
||||||
|
FDetails.Add(Format('RowIndex = %d (%s)', [r, ABS_REL[c and $4000 <> 0]]));
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [r, r]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'First row index');
|
||||||
|
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
r2 := WordLEToN(w);
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('RowIndex information:'#13);
|
||||||
|
FDetails.Add(Format('RowIndex = %d (%s)', [r2, ABS_REL[c and $4000 <> 0]]));
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [r2, r2]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Last row index');
|
||||||
|
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes); // column
|
||||||
|
c := WordLEToN(w);
|
||||||
|
Move(FBuffer[FBufferIndex+2], w, numBytes);
|
||||||
|
c2 := WordLEToN(w);
|
||||||
|
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('ColIndex information:'#13);
|
||||||
|
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c and $3FFF, ABS_REL[c and $8000 <> 0]]));
|
||||||
|
if c and $4000 = 0
|
||||||
|
then FDetails.Add('Bit 14=0: absolute row index')
|
||||||
|
else FDetails.Add('Bit 14=1: relative row index');
|
||||||
|
if c and $8000 = 0
|
||||||
|
then FDetails.Add('Bit 15=0: absolute column index')
|
||||||
|
else FDetails.Add('Bit 15=1: relative column index');
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [c, c]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'First column index');
|
||||||
|
|
||||||
|
if FCurrRow = Row then
|
||||||
|
begin
|
||||||
|
FDetails.Add('ColIndex information:'#13);
|
||||||
|
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c2 and $3FFF, ABS_REL[c2 and $8000 <> 0]]));
|
||||||
|
if c2 and $4000 = 0
|
||||||
|
then FDetails.Add('Bit 14=0: absolute row index')
|
||||||
|
else FDetails.Add('Bit 14=1: relative row index');
|
||||||
|
if c2 and $8000 = 0
|
||||||
|
then FDetails.Add('Bit 15=0: absolute column index')
|
||||||
|
else FDetails.Add('Bit 15=1: relative column index');
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [c2, c2]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Last column index');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
r := WordLEToN(w);
|
||||||
|
Move(FBuffer[FBufferIndex+2], w, numBytes);
|
||||||
|
r2 := WordLEToN(w);
|
||||||
|
|
||||||
|
numbytes := 1;
|
||||||
|
c := FBuffer[FBufferIndex+4];
|
||||||
|
c2 := FBuffer[FBufferIndex+5];
|
||||||
|
|
||||||
|
if FCurrRow = Row then
|
||||||
|
begin
|
||||||
|
FDetails.Add('RowIndex information:'#13);
|
||||||
|
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r and $3FFF, ABS_REL[r and $4000 <> 0]]));
|
||||||
|
if r and $4000 = 0
|
||||||
|
then FDetails.Add('Bit 14=0: absolute row index')
|
||||||
|
else FDetails.Add('Bit 14=1: relative row index');
|
||||||
|
if r and $8000 = 0
|
||||||
|
then FDetails.Add('Bit 15=0: absolute column index')
|
||||||
|
else FDetails.Add('Bit 15=1: relative column index');
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [r, r]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'First row index');
|
||||||
|
|
||||||
|
if FCurrRow = Row then
|
||||||
|
begin
|
||||||
|
FDetails.Add('RowIndex information:'#13);
|
||||||
|
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r2 and $3FFF, ABS_REL[r2 and $4000 <> 0]]));
|
||||||
|
if r2 and $4000 = 0
|
||||||
|
then FDetails.Add('Bit 14=0: absolute row index')
|
||||||
|
else FDetails.Add('Bit 14=1: relative row index');
|
||||||
|
if r2 and $8000 = 0
|
||||||
|
then FDetails.Add('Bit 15=0: absolute column index')
|
||||||
|
else FDetails.Add('Bit 15=1: relative column index');
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [r2, r2]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Last row index');
|
||||||
|
|
||||||
|
if FCurrRow = Row then
|
||||||
|
begin
|
||||||
|
FDetails.Add('ColIndex information:'#13);
|
||||||
|
FDetails.Add(Format('ColIndex = %d (%s)', [c, ABS_REL[r and $8000 <> 0]]));
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [c, c]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'First column index');
|
||||||
|
|
||||||
|
if FCurrRow = Row then
|
||||||
|
begin
|
||||||
|
FDetails.Add('ColIndex information:'#13);
|
||||||
|
FDetails.Add(Format('ColIndex = %d (%s)', [c2, ABS_REL[r2 and $8000 <> 0]]));
|
||||||
|
end;
|
||||||
|
s := Format('%d ($%.4x)', [c2, c2]);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Last column index');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TBIFFGrid.ShowClrtClient;
|
procedure TBIFFGrid.ShowClrtClient;
|
||||||
var
|
var
|
||||||
w: Word;
|
w: Word;
|
||||||
@ -888,10 +1082,18 @@ var
|
|||||||
widestr: WideString;
|
widestr: WideString;
|
||||||
s: String;
|
s: String;
|
||||||
macro: Boolean;
|
macro: Boolean;
|
||||||
|
formulaSize: Word;
|
||||||
|
firstTokenBufIdx: Integer;
|
||||||
|
token: Byte;
|
||||||
|
r,c, r2,c2: Integer;
|
||||||
begin
|
begin
|
||||||
if FFormat = sfExcel2 then begin
|
BeginUpdate;
|
||||||
RowCount := FixedRows + 7;
|
RowCount := FixedRows + 1000;
|
||||||
|
// Brute force simplification because of unknown row count at this point
|
||||||
|
// Will be reduced at the end.
|
||||||
|
|
||||||
|
if FFormat = sfExcel2 then
|
||||||
|
begin
|
||||||
numBytes := 1;
|
numBytes := 1;
|
||||||
b := FBuffer[FBufferIndex];
|
b := FBuffer[FBufferIndex];
|
||||||
isFuncMacro := b and $02 <> 0;
|
isFuncMacro := b and $02 <> 0;
|
||||||
@ -934,13 +1136,10 @@ begin
|
|||||||
b := FBuffer[FBufferIndex];
|
b := FBuffer[FBufferIndex];
|
||||||
ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(b),
|
ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(b),
|
||||||
'Size of the formula data');
|
'Size of the formula data');
|
||||||
|
formulaSize := b;
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 1, '',
|
end
|
||||||
'Formula data follow...');
|
else
|
||||||
end else
|
|
||||||
begin
|
begin
|
||||||
RowCount := FixedRows + 12;
|
|
||||||
|
|
||||||
numBytes := 2;
|
numBytes := 2;
|
||||||
Move(FBuffer[FBufferIndex], w, numBytes);
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
w := WordLEToN(w);
|
w := WordLEToN(w);
|
||||||
@ -1008,6 +1207,7 @@ begin
|
|||||||
w := WordLEToN(w);
|
w := WordLEToN(w);
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w),
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w),
|
||||||
'Size of the formula data');
|
'Size of the formula data');
|
||||||
|
formulaSize := w;
|
||||||
|
|
||||||
numBytes := 2;
|
numBytes := 2;
|
||||||
Move(FBuffer[FBufferIndex], w, numBytes);
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
@ -1065,18 +1265,70 @@ begin
|
|||||||
Move(FBuffer[FBufferIndex + 1], wideStr[1], lenName*SizeOf(WideChar));
|
Move(FBuffer[FBufferIndex + 1], wideStr[1], lenName*SizeOf(WideChar));
|
||||||
s := UTF8Encode(WideStringLEToN(wideStr));
|
s := UTF8Encode(WideStringLEToN(wideStr));
|
||||||
end;
|
end;
|
||||||
{
|
|
||||||
numBytes := lenName * SizeOf(wideChar);
|
|
||||||
SetLength(wideStr, lenName);
|
|
||||||
Move(FBuffer[FBufferIndex], wideStr[1], numBytes);
|
|
||||||
}
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numbytes, s,
|
ShowInRow(FCurrRow, FBufferIndex, numbytes, s,
|
||||||
'Name (Unicode string without length field)');
|
'Name (Unicode string without length field)');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 1, '',
|
|
||||||
'Formula data follow...');
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
firstTokenBufIdx := FBufferIndex;
|
||||||
|
while FBufferIndex < firstTokenBufIdx + formulaSize do begin
|
||||||
|
token := FBuffer[FBufferIndex];
|
||||||
|
numBytes := 1;
|
||||||
|
case token of
|
||||||
|
$3A, $3B, $5A, $5B, $7A, $7B:
|
||||||
|
begin
|
||||||
|
case token of
|
||||||
|
$3A: s := 'Token tRef3dR for "3D or external reference to a cell" (R = Reference)';
|
||||||
|
$5A: s := 'Token tRef3dV for "3D or external reference to a cell" (V = Value)';
|
||||||
|
$7A: s := 'Token tRef3dA for "3D or external reference to a cell" (A = Area)';
|
||||||
|
$3B: s := 'Token tArea3dR for "3D or external reference to a cell range" (R = Reference)';
|
||||||
|
$5B: s := 'Token tArea3dV for "3D or external reference to a cell range" (V = Value)';
|
||||||
|
$7B: s := 'Token tArea3dA for "3D or external reference to a cell range" (A = Area)';
|
||||||
|
end;
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [token]), s);
|
||||||
|
|
||||||
|
numbytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
w := WordLEToN(w);
|
||||||
|
if FFormat = sfExcel5 then begin
|
||||||
|
if w and $8000 <> 0 then begin // negative value --> 3D reference
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(SmallInt(w)),
|
||||||
|
'3D reference, 1-based index to EXTERNSHEET record');
|
||||||
|
numBytes := 8;
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, '', 'Not used');
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
|
||||||
|
'Index to first referenced sheet ($FFFF = deleted sheet)');
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
|
||||||
|
'Index to last referenced sheet ($FFFF = deleted sheet)');
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w),
|
||||||
|
'External reference, 1-based index to EXTERNSHEET record');
|
||||||
|
numBytes := 12;
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, '', 'Not used');
|
||||||
|
end;
|
||||||
|
end else
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w),
|
||||||
|
'Index to REF entry in EXTERNSHEET record');
|
||||||
|
|
||||||
|
if token in [$3A, $5A, $7A] then
|
||||||
|
ShowCellAddress // Cell address
|
||||||
|
else
|
||||||
|
ShowCellAddressRange; // Cell range
|
||||||
|
end;
|
||||||
|
|
||||||
|
else
|
||||||
|
numBytes := 1;
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
|
'(unknown token)');
|
||||||
|
end; // case
|
||||||
|
end; // while
|
||||||
|
|
||||||
|
RowCount := FCurrRow;
|
||||||
|
EndUpdate(true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TBIFFGrid.ShowDefRowHeight;
|
procedure TBIFFGrid.ShowDefRowHeight;
|
||||||
@ -1217,6 +1469,141 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBIFFGrid.ShowExternalBook;
|
||||||
|
var
|
||||||
|
numBytes: Integer;
|
||||||
|
w: Word;
|
||||||
|
wideStr: WideString;
|
||||||
|
ansiStr: AnsiString;
|
||||||
|
s: String;
|
||||||
|
i, n: Integer;
|
||||||
|
begin
|
||||||
|
BeginUpdate;
|
||||||
|
RowCount := FixedRows + 1000;
|
||||||
|
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
n := WordLEToN(w);
|
||||||
|
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(n),
|
||||||
|
'Number of sheet names / number of sheets');
|
||||||
|
|
||||||
|
if Length(FBuffer) - FBufferIndex = 2 then begin
|
||||||
|
SetLength(ansiStr, 1);
|
||||||
|
Move(FBuffer[FBufferIndex], ansiStr[1], 1);
|
||||||
|
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s,
|
||||||
|
'(relict of BIFF5)');
|
||||||
|
end else begin
|
||||||
|
ExtractString(FBufferIndex, 2, true, s, numBytes);
|
||||||
|
if Row = FCurrRow then begin
|
||||||
|
FDetails.Add('Encoded URL without sheet name:'#13);
|
||||||
|
case s[1] of
|
||||||
|
#0: FDetails.Add('First character = #00: Reference relative to current sheet');
|
||||||
|
#1: FDetails.Add('First character = #01: Encoded URL follows');
|
||||||
|
#2: if FFormat = sfExcel8 then
|
||||||
|
FDetails.Add('First character = #02: Reference to a sheet in own document; sheet name follows')
|
||||||
|
else
|
||||||
|
FDetails.Add('First character = #02: Reference to the corrent sheet (nothing will follow)');
|
||||||
|
#3: if FFormat = sfExcel5 then
|
||||||
|
FDetails.Add('First character = #03: Reference to a sheet in own document; sheet name follows')
|
||||||
|
else
|
||||||
|
FDetails.Add('First character = #03: not used');
|
||||||
|
#4: if FFormat = sfExcel5 then
|
||||||
|
FDetails.ADd('First character = #03: Reference to the own workbook, sheet is unspecified (nothing will follow)')
|
||||||
|
else
|
||||||
|
FDetails.Add('First character = #03: not used');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if s[1] in [#0, #1, #2, #3, #4] then Delete(s, 1, 1);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s,
|
||||||
|
'Encoded URL without sheet name (Unicode string, 16-bit string length)');
|
||||||
|
|
||||||
|
for i:=0 to n-1 do begin
|
||||||
|
ExtractString(FBufferIndex, 2, true, s, numBytes);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s,
|
||||||
|
'Sheet name (Unicode string with 16-bit string length)');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
RowCount := FCurrRow;
|
||||||
|
EndUpdate(true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBIFFGrid.ShowExternCount;
|
||||||
|
var
|
||||||
|
numBytes: Integer;
|
||||||
|
w: Word;
|
||||||
|
begin
|
||||||
|
RowCount := FixedRows + 1;
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
|
||||||
|
'Number of following EXTERNSHEET records');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TBIFFGrid.ShowExternSheet;
|
||||||
|
var
|
||||||
|
numBytes: Integer;
|
||||||
|
w: Word;
|
||||||
|
s: String;
|
||||||
|
nREF: Integer;
|
||||||
|
i: Integer;
|
||||||
|
len: Byte;
|
||||||
|
ansiStr: AnsiString;
|
||||||
|
begin
|
||||||
|
if FFormat <= sfExcel5 then begin
|
||||||
|
RowCount := FixedRows + 1;
|
||||||
|
len := FBuffer[0];
|
||||||
|
if FBuffer[1] = $03 then inc(len);
|
||||||
|
numBytes := len*SizeOf(AnsiChar) + 1;
|
||||||
|
SetLength(ansiStr, len);
|
||||||
|
Move(FBuffer[1], ansiStr[1], len*SizeOf(AnsiChar));
|
||||||
|
s := AnsiToUTF8(ansiStr);
|
||||||
|
if FCurrRow = Row then begin
|
||||||
|
FDetails.Add('Encoded document and sheet name:'#13);
|
||||||
|
if s[1] = #03 then begin
|
||||||
|
FDetails.Add('First character = $03: EXTERNSHEET stores a reference to one of the own sheets');
|
||||||
|
FDetails.Add('Document name: ' + Copy(s, 2, Length(s)));
|
||||||
|
end else
|
||||||
|
if (s[1] = ':') and (Length(s) = 1) then begin
|
||||||
|
FDetails.Add('Special EXTERNSHEET record for an add-in function. EXTERNName record with the name of the function follows.');
|
||||||
|
end else
|
||||||
|
FDetails.Add('Document name: ' + s);
|
||||||
|
end;
|
||||||
|
if s[1] = #03 then
|
||||||
|
Delete(s, 1, 1);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, s,
|
||||||
|
'Encoded document and sheet name (Byte string, 8-bit string length)');
|
||||||
|
end else begin
|
||||||
|
numBytes := 2;
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
nREF := WordLEToN(w);
|
||||||
|
|
||||||
|
RowCount := FixedRows + 1 + nREF*3;
|
||||||
|
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(nREF),
|
||||||
|
'Number of following REF structures');
|
||||||
|
|
||||||
|
for i:=1 to nREF do begin
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
|
||||||
|
Format('REF #%d: Index to EXTERNALBOOK record', [i]));
|
||||||
|
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
|
||||||
|
Format('REF #%d: Index to first sheet in EXTERNALBOOK sheet list', [i]));
|
||||||
|
|
||||||
|
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||||
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)),
|
||||||
|
Format('REF #%d: Index to last sheet in EXTERNALBOOK sheet list', [i]));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TBIFFGrid.ShowFileSharing;
|
procedure TBIFFGrid.ShowFileSharing;
|
||||||
var
|
var
|
||||||
numbytes: Integer;
|
numbytes: Integer;
|
||||||
@ -1537,8 +1924,6 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
procedure TBIFFGrid.ShowFormula;
|
procedure TBIFFGrid.ShowFormula;
|
||||||
const
|
|
||||||
ABS_REL: array[boolean] of string = ('abs', 'rel');
|
|
||||||
var
|
var
|
||||||
numBytes: Integer;
|
numBytes: Integer;
|
||||||
b: Byte;
|
b: Byte;
|
||||||
@ -1694,79 +2079,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
(*
|
|
||||||
if (FFormat > sfExcel2) then begin
|
|
||||||
if wordarr[3] <> $FFFF then begin
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('Formula result:'#13);
|
|
||||||
FDetails.Add(Format('Bytes 0-7: $%.15x --> IEEE 764 floating-point value, 64-bit double precision'#13+
|
|
||||||
' = %g', [q, dbl]));
|
|
||||||
end;
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl),
|
|
||||||
'Result of formula (IEEE 764 floating-point value, 64-bit double precision)');
|
|
||||||
end else begin
|
|
||||||
case bytearr[0] of
|
|
||||||
0: begin
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('Formula result:'#13);
|
|
||||||
FDetails.Add('Byte 0 = 0 --> Result is string, follows in STRING record');
|
|
||||||
FDetails.Add('Byte 1-5: Not used');
|
|
||||||
FDetails.Add('Byte 6&7: $FFFF --> no floating point number');
|
|
||||||
end;
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.16x', [q]),
|
|
||||||
'Result is a string, follows in STRING record');
|
|
||||||
end;
|
|
||||||
1: begin
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('Formula result:'#13);
|
|
||||||
FDetails.Add('Byte 0 = 1 --> Result is BOOLEAN');
|
|
||||||
FDetails.Add('Byte 1: Not used');
|
|
||||||
if bytearr[2] = 0
|
|
||||||
then FDetails.Add('Byte 2 = 0 --> FALSE')
|
|
||||||
else FDetails.Add('Byte 2 = 1 --> TRUE');
|
|
||||||
FDetails.Add('Bytes 3-5: Not used');
|
|
||||||
FDetails.Add('Bytes 6&7: $FFFF --> no floating point number');
|
|
||||||
end;
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.16x', [q]),
|
|
||||||
'Result is BOOLEAN');
|
|
||||||
end;
|
|
||||||
2: begin
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('Formula result:'#13);
|
|
||||||
FDetails.Add('Byte 0 = 2 --> Result is an ERROR value');
|
|
||||||
FDetails.Add('Byte 1: Not used');
|
|
||||||
case bytearr[2] of
|
|
||||||
$00: FDetails.Add('Byte 2 = $00 --> #NULL! Intersection of two cell ranges is empty');
|
|
||||||
$07: FDetails.Add('Byte 2 = $07 --> #DIV/0! Division by zero');
|
|
||||||
$0F: FDetails.Add('Byte 2 = $0F --> #VALUE! Wrong type of operand');
|
|
||||||
$17: FDetails.Add('Byte 2 = $17 --> #REF! Illegal or deleted cell reference');
|
|
||||||
$1D: FDetails.Add('Byte 2 = $1D --> #NAME? Wrong function or range name');
|
|
||||||
$24: FDetails.Add('Byte 2 = $24 --> #NUM! Value range overflow');
|
|
||||||
$2A: FDetails.Add('Byte 2 = $2A --> #N/A Argument or function not available');
|
|
||||||
end;
|
|
||||||
FDetails.Add('Bytes 6&7: $FFFF --> no floating point number');
|
|
||||||
end;
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.16x', [q]),
|
|
||||||
'Result is an ERROR value');
|
|
||||||
end;
|
|
||||||
3: begin
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('Formula result:'#13);
|
|
||||||
FDetails.Add('Byte 0 = 3 --> Result is an empty cell, for example an empty string');
|
|
||||||
FDetails.Add('Byte 1-5: Not used');
|
|
||||||
FDetails.Add('Bytes 6&7: $FFFF --> no floating point number');
|
|
||||||
end;
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.16x', [q]),
|
|
||||||
'Result is an EMPTY cell (empty string)');
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else begin // Excel 2
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl),
|
|
||||||
'Result of formula (IEEE 764 floating-point value, 64-bit double precision)');
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
// Option flags
|
// Option flags
|
||||||
if FFormat = sfExcel2 then begin
|
if FFormat = sfExcel2 then begin
|
||||||
numBytes := 1;
|
numBytes := 1;
|
||||||
@ -1882,8 +2195,6 @@ begin
|
|||||||
'Token "&" (concat)');
|
'Token "&" (concat)');
|
||||||
$09: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
$09: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
'Token "<" (less than)');
|
'Token "<" (less than)');
|
||||||
$15: ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [token]),
|
|
||||||
'Token "()" (operator in parenthesis)');
|
|
||||||
$0A: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
$0A: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
'Token "<=" (less equal)');
|
'Token "<=" (less equal)');
|
||||||
$0B: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
$0B: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
@ -1906,6 +2217,8 @@ begin
|
|||||||
'Token "-" (unary minus)');
|
'Token "-" (unary minus)');
|
||||||
$14: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
$14: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
'Token "%" (percent)');
|
'Token "%" (percent)');
|
||||||
|
$15: ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [token]),
|
||||||
|
'Token "()" (operator in parenthesis)');
|
||||||
$16: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
$16: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
'Token "missing argument"');
|
'Token "missing argument"');
|
||||||
$17: begin
|
$17: begin
|
||||||
@ -2022,56 +2335,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
Format('Token tREF (Cell %s)', [s]));
|
Format('Token tREF (Cell %s)', [s]));
|
||||||
numBytes := 2;
|
ShowCellAddress;
|
||||||
Move(FBuffer[FBufferIndex], w, numBytes); // row --> w
|
|
||||||
r := WordLEToN(w);
|
|
||||||
if FFormat = sfExcel8 then begin
|
|
||||||
numBytes := 2;
|
|
||||||
Move(FBuffer[FBufferIndex+2], w, numBytes); // column --w1
|
|
||||||
c := WordLEToN(w);
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('RowIndex information:'#13);
|
|
||||||
FDetails.Add(Format('RowIndex = %d (%s)', [r, ABS_REL[c and $4000 <> 0]]));
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [r, r]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Row index');
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('ColIndex information:'#13);
|
|
||||||
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c and $3FFF, ABS_REL[c and $8000 <> 0]]));
|
|
||||||
if c and $4000 = 0
|
|
||||||
then FDetails.Add('Bit 14=0: absolute row index')
|
|
||||||
else FDetails.Add('Bit 14=1: relative row index');
|
|
||||||
if c and $8000 = 0
|
|
||||||
then FDetails.Add('Bit 15=0: absolute column index')
|
|
||||||
else FDetails.Add('Bit 15=1: relative column index');
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [c, c]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Column index');
|
|
||||||
end else begin
|
|
||||||
numbytes := 1;
|
|
||||||
Move(FBuffer[FBufferIndex+2], b, numBytes);
|
|
||||||
c := b;
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('RowIndex information:'#13);
|
|
||||||
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r and $3FFF, ABS_REL[r and $4000 <> 0]]));
|
|
||||||
if r and $4000 = 0
|
|
||||||
then FDetails.Add('Bit 14=0: absolute row index')
|
|
||||||
else FDetails.Add('Bit 14=1: relative row index');
|
|
||||||
if r and $8000 = 0
|
|
||||||
then FDetails.Add('Bit 15=0: absolute column index')
|
|
||||||
else FDetails.Add('Bit 15=1: relative column index');
|
|
||||||
end;
|
|
||||||
//s := Format('$%.4x (%d, %s)', [r, r and $3FFF, ABS_REL[r and $4000 <> 0]]);
|
|
||||||
s := Format('%d ($%.4x)', [r, r]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Row index');
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('ColIndex information:'#13);
|
|
||||||
FDetails.Add(Format('ColIndex = %d (%s)', [c, ABS_REL[r and $8000 <> 0]]));
|
|
||||||
end;
|
|
||||||
//s := Format('$%.2x (%d, %s)', [c, c, ABS_REL[r and $8000 <> 0]]);
|
|
||||||
s := Format('%d ($%.4x)', [c, c]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Column index');
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
$25, $45, $65:
|
$25, $45, $65:
|
||||||
begin
|
begin
|
||||||
@ -2082,138 +2346,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
Format('Token tAREA (Cell range %s)', [s]));
|
Format('Token tAREA (Cell range %s)', [s]));
|
||||||
|
ShowCellAddressRange;
|
||||||
if FFormat = sfExcel8 then begin
|
|
||||||
numBytes := 2;
|
|
||||||
Move(FBuffer[FBufferIndex], w, numBytes);
|
|
||||||
r := WordLEToN(w);
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('RowIndex information:'#13);
|
|
||||||
FDetails.Add(Format('RowIndex = %d (%s)', [r, ABS_REL[c and $4000 <> 0]]));
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [r, r]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'First row index');
|
|
||||||
|
|
||||||
Move(FBuffer[FBufferIndex], w, numBytes);
|
|
||||||
r2 := WordLEToN(w);
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('RowIndex information:'#13);
|
|
||||||
FDetails.Add(Format('RowIndex = %d (%s)', [r2, ABS_REL[c and $4000 <> 0]]));
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [r2, r2]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Last row index');
|
|
||||||
|
|
||||||
Move(FBuffer[FBufferIndex], w, numBytes); // column
|
|
||||||
c := WordLEToN(w);
|
|
||||||
Move(FBuffer[FBufferIndex+2], w, numBytes);
|
|
||||||
c2 := WordLEToN(w);
|
|
||||||
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('ColIndex information:'#13);
|
|
||||||
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c and $3FFF, ABS_REL[c and $8000 <> 0]]));
|
|
||||||
if c and $4000 = 0
|
|
||||||
then FDetails.Add('Bit 14=0: absolute row index')
|
|
||||||
else FDetails.Add('Bit 14=1: relative row index');
|
|
||||||
if c and $8000 = 0
|
|
||||||
then FDetails.Add('Bit 15=0: absolute column index')
|
|
||||||
else FDetails.Add('Bit 15=1: relative column index');
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [c, c]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'First column index');
|
|
||||||
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('ColIndex information:'#13);
|
|
||||||
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c2 and $3FFF, ABS_REL[c2 and $8000 <> 0]]));
|
|
||||||
if c2 and $4000 = 0
|
|
||||||
then FDetails.Add('Bit 14=0: absolute row index')
|
|
||||||
else FDetails.Add('Bit 14=1: relative row index');
|
|
||||||
if c2 and $8000 = 0
|
|
||||||
then FDetails.Add('Bit 15=0: absolute column index')
|
|
||||||
else FDetails.Add('Bit 15=1: relative column index');
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [c2, c2]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Last column index');
|
|
||||||
|
|
||||||
end else begin
|
|
||||||
|
|
||||||
numBytes := 2;
|
|
||||||
Move(FBuffer[FBufferIndex], w, numBytes);
|
|
||||||
r := WordLEToN(w);
|
|
||||||
Move(FBuffer[FBufferIndex+2], w, numBytes);
|
|
||||||
r2 := WordLEToN(w);
|
|
||||||
|
|
||||||
numbytes := 1;
|
|
||||||
c := FBuffer[FBufferIndex+4];
|
|
||||||
c2 := FBuffer[FBufferIndex+5];
|
|
||||||
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('RowIndex information:'#13);
|
|
||||||
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r and $3FFF, ABS_REL[r and $4000 <> 0]]));
|
|
||||||
if r and $4000 = 0
|
|
||||||
then FDetails.Add('Bit 14=0: absolute row index')
|
|
||||||
else FDetails.Add('Bit 14=1: relative row index');
|
|
||||||
if r and $8000 = 0
|
|
||||||
then FDetails.Add('Bit 15=0: absolute column index')
|
|
||||||
else FDetails.Add('Bit 15=1: relative column index');
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [r, r]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'First row index');
|
|
||||||
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('RowIndex information:'#13);
|
|
||||||
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r2 and $3FFF, ABS_REL[r2 and $4000 <> 0]]));
|
|
||||||
if r2 and $4000 = 0
|
|
||||||
then FDetails.Add('Bit 14=0: absolute row index')
|
|
||||||
else FDetails.Add('Bit 14=1: relative row index');
|
|
||||||
if r2 and $8000 = 0
|
|
||||||
then FDetails.Add('Bit 15=0: absolute column index')
|
|
||||||
else FDetails.Add('Bit 15=1: relative column index');
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [r2, r2]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Last row index');
|
|
||||||
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('ColIndex information:'#13);
|
|
||||||
FDetails.Add(Format('ColIndex = %d (%s)', [c, ABS_REL[r and $8000 <> 0]]));
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [c, c]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'First column index');
|
|
||||||
|
|
||||||
if FCurrRow = Row then begin
|
|
||||||
FDetails.Add('ColIndex information:'#13);
|
|
||||||
FDetails.Add(Format('ColIndex = %d (%s)', [c2, ABS_REL[r2 and $8000 <> 0]]));
|
|
||||||
end;
|
|
||||||
s := Format('%d ($%.4x)', [c2, c2]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Last column index');
|
|
||||||
end;
|
|
||||||
{
|
|
||||||
if FFormat = sfExcel8 then begin
|
|
||||||
numBytes := 2;
|
|
||||||
Move(FBuffer[FBufferIndex+4], w, numBytes);
|
|
||||||
c := WordLEToN(w);
|
|
||||||
Move(FBuffer[FBufferIndex+6], w, numBytes);
|
|
||||||
c2 := WordLEToN(w);
|
|
||||||
s := Format('$%.4x (%d, %s)', [r, r, ABS_REL[c and $4000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Index to first row');
|
|
||||||
s := Format('$%.4x (%d, %s)', [r2, r2, ABS_REL[c2 and $4000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Index to last row');
|
|
||||||
s := Format('$%.4x (%d, %s)', [c, c and $3FFF, ABS_REL[c and $8000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Index to first column');
|
|
||||||
s := Format('$%.4x (%d, %s)', [c2, c2 and $3FFF, ABS_REL[c2 and $8000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Index to last columns');
|
|
||||||
end else begin
|
|
||||||
c := FBuffer[FBufferIndex+4];
|
|
||||||
c2 := FBuffer[FBufferIndex+5];
|
|
||||||
s := Format('$%.4x (%d, %s)', [r, r and $3FFF, ABS_REL[r and $4000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Index to first row');
|
|
||||||
s := Format('$%.4x (%d, %s)', [r2, r2 and $3FFF, ABS_REL[r2 and $4000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Index to last row');
|
|
||||||
s := Format('$%.2x (%d, %s)', [c, c, ABS_REL[r and $8000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 1, s, 'Index to first column');
|
|
||||||
s := Format('$%.2x (%d, %s)', [c2, c2, ABS_REL[r2 and $8000 <> 0]]);
|
|
||||||
ShowInRow(FCurrRow, FBufferIndex, 1, s, 'Index to last column');
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
end;
|
end;
|
||||||
else ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
else ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||||
'(unknown)');
|
'(unknown)');
|
||||||
@ -2222,7 +2355,6 @@ begin
|
|||||||
|
|
||||||
RowCount := FCurrRow;
|
RowCount := FCurrRow;
|
||||||
EndUpdate(true);
|
EndUpdate(true);
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -2363,6 +2495,11 @@ var
|
|||||||
numbytes: Integer;
|
numbytes: Integer;
|
||||||
w: Word;
|
w: Word;
|
||||||
begin
|
begin
|
||||||
|
if FFormat < sfExcel8 then begin
|
||||||
|
RowCount := FixedRows;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
RowCount := FixedRows + 1;
|
RowCount := FixedRows + 1;
|
||||||
numbytes := 2;
|
numbytes := 2;
|
||||||
Move(FBuffer[FBufferIndex], w, numbytes);
|
Move(FBuffer[FBufferIndex], w, numbytes);
|
||||||
|
@ -15,15 +15,18 @@ object MainForm: TMainForm
|
|||||||
LCLVersion = '1.3'
|
LCLVersion = '1.3'
|
||||||
object Splitter1: TSplitter
|
object Splitter1: TSplitter
|
||||||
Left = 419
|
Left = 419
|
||||||
Height = 497
|
Height = 496
|
||||||
Top = 26
|
Top = 27
|
||||||
Width = 5
|
Width = 5
|
||||||
end
|
end
|
||||||
object ToolBar: TToolBar
|
object ToolBar: TToolBar
|
||||||
Left = 0
|
Left = 4
|
||||||
Height = 26
|
Height = 27
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 1089
|
Width = 1085
|
||||||
|
AutoSize = True
|
||||||
|
BorderSpacing.Left = 4
|
||||||
|
ButtonHeight = 25
|
||||||
Caption = 'ToolBar'
|
Caption = 'ToolBar'
|
||||||
Images = ImageList
|
Images = ImageList
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
@ -54,17 +57,17 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object DetailPanel: TPanel
|
object DetailPanel: TPanel
|
||||||
Left = 424
|
Left = 424
|
||||||
Height = 497
|
Height = 496
|
||||||
Top = 26
|
Top = 27
|
||||||
Width = 665
|
Width = 665
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
ClientHeight = 497
|
ClientHeight = 496
|
||||||
ClientWidth = 665
|
ClientWidth = 665
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
object PageControl: TPageControl
|
object PageControl: TPageControl
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 497
|
Height = 496
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 665
|
Width = 665
|
||||||
ActivePage = PgValues
|
ActivePage = PgValues
|
||||||
@ -104,12 +107,12 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object PgValues: TTabSheet
|
object PgValues: TTabSheet
|
||||||
Caption = 'Values'
|
Caption = 'Values'
|
||||||
ClientHeight = 464
|
ClientHeight = 463
|
||||||
ClientWidth = 657
|
ClientWidth = 657
|
||||||
object ValueGrid: TStringGrid
|
object ValueGrid: TStringGrid
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 158
|
Height = 158
|
||||||
Top = 306
|
Top = 305
|
||||||
Width = 657
|
Width = 657
|
||||||
Align = alBottom
|
Align = alBottom
|
||||||
ColCount = 3
|
ColCount = 3
|
||||||
@ -140,17 +143,17 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object HexPanel: TPanel
|
object HexPanel: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 301
|
Height = 300
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 657
|
Width = 657
|
||||||
Align = alClient
|
Align = alClient
|
||||||
Caption = 'HexPanel'
|
Caption = 'HexPanel'
|
||||||
ClientHeight = 301
|
ClientHeight = 300
|
||||||
ClientWidth = 657
|
ClientWidth = 657
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
object HexGrid: TStringGrid
|
object HexGrid: TStringGrid
|
||||||
Left = 1
|
Left = 1
|
||||||
Height = 299
|
Height = 298
|
||||||
Top = 1
|
Top = 1
|
||||||
Width = 390
|
Width = 390
|
||||||
Align = alClient
|
Align = alClient
|
||||||
@ -238,7 +241,7 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object AlphaGrid: TStringGrid
|
object AlphaGrid: TStringGrid
|
||||||
Left = 396
|
Left = 396
|
||||||
Height = 299
|
Height = 298
|
||||||
Top = 1
|
Top = 1
|
||||||
Width = 260
|
Width = 260
|
||||||
Align = alRight
|
Align = alRight
|
||||||
@ -323,7 +326,7 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object HexDumpSplitter: TSplitter
|
object HexDumpSplitter: TSplitter
|
||||||
Left = 391
|
Left = 391
|
||||||
Height = 299
|
Height = 298
|
||||||
Top = 1
|
Top = 1
|
||||||
Width = 5
|
Width = 5
|
||||||
Align = alRight
|
Align = alRight
|
||||||
@ -334,7 +337,7 @@ object MainForm: TMainForm
|
|||||||
Cursor = crVSplit
|
Cursor = crVSplit
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 5
|
Height = 5
|
||||||
Top = 301
|
Top = 300
|
||||||
Width = 657
|
Width = 657
|
||||||
Align = alBottom
|
Align = alBottom
|
||||||
ResizeAnchor = akBottom
|
ResizeAnchor = akBottom
|
||||||
@ -344,19 +347,19 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object TreePanel: TPanel
|
object TreePanel: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 497
|
Height = 496
|
||||||
Top = 26
|
Top = 27
|
||||||
Width = 419
|
Width = 419
|
||||||
Align = alLeft
|
Align = alLeft
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
ClientHeight = 497
|
ClientHeight = 496
|
||||||
ClientWidth = 419
|
ClientWidth = 419
|
||||||
Constraints.MinWidth = 275
|
Constraints.MinWidth = 275
|
||||||
TabOrder = 3
|
TabOrder = 3
|
||||||
object FindPanel: TPanel
|
object FindPanel: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 36
|
Height = 36
|
||||||
Top = 461
|
Top = 460
|
||||||
Width = 419
|
Width = 419
|
||||||
Align = alBottom
|
Align = alBottom
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
@ -509,7 +512,7 @@ object MainForm: TMainForm
|
|||||||
end
|
end
|
||||||
object BIFFTree: TVirtualStringTree
|
object BIFFTree: TVirtualStringTree
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 461
|
Height = 460
|
||||||
Top = 0
|
Top = 0
|
||||||
Width = 419
|
Width = 419
|
||||||
Align = alClient
|
Align = alClient
|
||||||
|
@ -142,6 +142,7 @@ type
|
|||||||
FFontIndex: Integer;
|
FFontIndex: Integer;
|
||||||
FFormatIndex: Integer;
|
FFormatIndex: Integer;
|
||||||
FRowIndex: Integer;
|
FRowIndex: Integer;
|
||||||
|
FExternSheetIndex: Integer;
|
||||||
FLockHexDumpGrids: Integer;
|
FLockHexDumpGrids: Integer;
|
||||||
FAnalysisGrid: TBIFFGrid;
|
FAnalysisGrid: TBIFFGrid;
|
||||||
FMRUMenuManager : TMRUMenuManager;
|
FMRUMenuManager : TMRUMenuManager;
|
||||||
@ -1112,6 +1113,7 @@ begin
|
|||||||
FFontIndex := -1;
|
FFontIndex := -1;
|
||||||
FFormatIndex := -1;
|
FFormatIndex := -1;
|
||||||
FRowIndex := -1;
|
FRowIndex := -1;
|
||||||
|
FExternSheetIndex := 0; // 1-based!
|
||||||
AStream.Position := 0;
|
AStream.Position := 0;
|
||||||
while AStream.Position < AStream.Size do begin
|
while AStream.Position < AStream.Size do begin
|
||||||
p := AStream.Position;
|
p := AStream.Position;
|
||||||
@ -1165,6 +1167,11 @@ begin
|
|||||||
inc(FXFIndex);
|
inc(FXFIndex);
|
||||||
data.Index := FXFIndex;
|
data.Index := FXFIndex;
|
||||||
end;
|
end;
|
||||||
|
$0017: // EXTERNSHEET record
|
||||||
|
if FFormat < sfExcel8 then begin
|
||||||
|
inc(FExternSheetIndex);
|
||||||
|
data.Index := FExternSheetIndex;
|
||||||
|
end;
|
||||||
$001E, $041E: // Format record
|
$001E, $041E: // Format record
|
||||||
begin
|
begin
|
||||||
inc(FFormatIndex);
|
inc(FFormatIndex);
|
||||||
|
Reference in New Issue
Block a user