diff --git a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.ico b/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.ico deleted file mode 100644 index 7ce4cfe07..000000000 Binary files a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.ico and /dev/null differ diff --git a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpi b/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpi deleted file mode 100644 index 20be0cb9f..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpi +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - <ResourceType Value="res"/> - <UseXPManifest Value="True"/> - <XPManifest> - <DpiAware Value="True"/> - </XPManifest> - <Icon Value="0"/> - </General> - <i18n> - <EnableI18N LFM="False"/> - </i18n> - <VersionInfo> - <StringTable ProductVersion=""/> - </VersionInfo> - <BuildModes Count="3"> - <Item1 Name="Release" Default="True"/> - <Item2 Name="Debug"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <Target> - <Filename Value="bin\$(TargetCPU)-$(TargetOS)\BiffExplorer"/> - </Target> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir)"/> - <OtherUnitFiles Value="mrumenu"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <Linking> - <Debugging> - <DebugInfoType Value="dsDwarf2Set"/> - <UseExternalDbgSyms Value="True"/> - </Debugging> - <Options> - <Win32> - <GraphicApplication Value="True"/> - </Win32> - </Options> - </Linking> - <Other> - <CustomOptions Value="-duse_new_ole"/> - </Other> - </CompilerOptions> - </Item2> - <Item3 Name="Debug with heaptrace"> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir)"/> - <OtherUnitFiles Value="mrumenu"/> - <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="dsStabs"/> - <UseHeaptrc Value="True"/> - </Debugging> - <Options> - <Win32> - <GraphicApplication Value="True"/> - </Win32> - </Options> - </Linking> - <Other> - <CustomOptions Value="-duse_new_ole"/> - </Other> - </CompilerOptions> - </Item3> - <SharedMatrixOptions Count="1"> - <Item1 ID="897672969650" Value="-vd"/> - </SharedMatrixOptions> - </BuildModes> - <PublishOptions> - <Version Value="2"/> - </PublishOptions> - <RunParams> - <local> - <FormatVersion Value="1"/> - </local> - </RunParams> - <RequiredPackages Count="5"> - <Item1> - <PackageName Value="KControlsLaz"/> - </Item1> - <Item2> - <PackageName Value="laz_fpspreadsheet"/> - </Item2> - <Item3> - <PackageName Value="TurboPowerIPro"/> - </Item3> - <Item4> - <PackageName Value="virtualtreeview_package"/> - </Item4> - <Item5> - <PackageName Value="LCL"/> - </Item5> - </RequiredPackages> - <Units Count="11"> - <Unit0> - <Filename Value="BIFFExplorer.lpr"/> - <IsPartOfProject Value="True"/> - </Unit0> - <Unit1> - <Filename Value="beabout.pas"/> - <IsPartOfProject Value="True"/> - <ComponentName Value="AboutForm"/> - <HasResources Value="True"/> - <ResourceBaseClass Value="Form"/> - <UnitName Value="beAbout"/> - </Unit1> - <Unit2> - <Filename Value="bebiffgrid.pas"/> - <IsPartOfProject Value="True"/> - <UnitName Value="beBIFFGrid"/> - </Unit2> - <Unit3> - <Filename Value="bebiffutils.pas"/> - <IsPartOfProject Value="True"/> - <UnitName Value="beBIFFUtils"/> - </Unit3> - <Unit4> - <Filename Value="behtml.pas"/> - <IsPartOfProject Value="True"/> - </Unit4> - <Unit5> - <Filename Value="bemain.pas"/> - <IsPartOfProject Value="True"/> - <ComponentName Value="MainForm"/> - <HasResources Value="True"/> - <ResourceBaseClass Value="Form"/> - <UnitName Value="beMain"/> - </Unit5> - <Unit6> - <Filename Value="beutils.pas"/> - <IsPartOfProject Value="True"/> - <UnitName Value="beUtils"/> - </Unit6> - <Unit7> - <Filename Value="mrumanager.pp"/> - <IsPartOfProject Value="True"/> - </Unit7> - <Unit8> - <Filename Value="bemain.lfm"/> - <IsPartOfProject Value="True"/> - </Unit8> - <Unit9> - <Filename Value="beabout.lfm"/> - <IsPartOfProject Value="True"/> - </Unit9> - <Unit10> - <Filename Value="betypes.pas"/> - <IsPartOfProject Value="True"/> - <UnitName Value="beTypes"/> - </Unit10> - </Units> - </ProjectOptions> - <CompilerOptions> - <Version Value="11"/> - <PathDelim Value="\"/> - <SearchPaths> - <IncludeFiles Value="$(ProjOutDir)"/> - <OtherUnitFiles Value="mrumenu"/> - <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> - </SearchPaths> - <CodeGeneration> - <SmartLinkUnit Value="True"/> - <Optimizations> - <OptimizationLevel Value="3"/> - </Optimizations> - </CodeGeneration> - <Linking> - <Debugging> - <GenerateDebugInfo Value="False"/> - </Debugging> - <LinkSmart Value="True"/> - <Options> - <Win32> - <GraphicApplication Value="True"/> - </Win32> - </Options> - </Linking> - <Other> - <CustomOptions Value="-duse_new_ole"/> - </Other> - </CompilerOptions> - <Debugging> - <Exceptions Count="4"> - <Item1> - <Name Value="EAbort"/> - </Item1> - <Item2> - <Name Value="ECodetoolError"/> - </Item2> - <Item3> - <Name Value="EFOpenError"/> - </Item3> - <Item4> - <Name Value="EStreamError"/> - </Item4> - </Exceptions> - </Debugging> -</CONFIG> diff --git a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpr b/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpr deleted file mode 100644 index 4e9abfb96..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpr +++ /dev/null @@ -1,22 +0,0 @@ -program BIFFExplorer; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset - Forms, virtualtreeview_package, laz_fpspreadsheet, kcontrolslaz, beabout, - bebiffgrid, bebiffutils, behtml, beutils, mrumanager, beMain, beTypes; - -{$R *.res} - -begin - RequireDerivedFormResource := True; - Application.Initialize; - Application.CreateForm(TMainForm, MainForm); - MainForm.BeforeRun; - Application.Run; -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.res b/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.res deleted file mode 100644 index 701ea761f..000000000 Binary files a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.res and /dev/null differ diff --git a/components/fpspreadsheet/reference/BIFFExplorer/beabout.lfm b/components/fpspreadsheet/reference/BIFFExplorer/beabout.lfm deleted file mode 100644 index adecc1421..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/beabout.lfm +++ /dev/null @@ -1,68 +0,0 @@ -object AboutForm: TAboutForm - Left = 338 - Height = 512 - Top = 153 - Width = 642 - Caption = 'About BIFF Explorer' - ClientHeight = 512 - ClientWidth = 642 - Color = clWindow - OnCreate = FormCreate - Position = poMainFormCenter - LCLVersion = '1.7' - object Panel1: TPanel - Left = 0 - Height = 66 - Top = 0 - Width = 642 - Align = alTop - BevelOuter = bvNone - ClientHeight = 66 - ClientWidth = 642 - Color = clWindow - ParentColor = False - TabOrder = 0 - object IconImage: TImage - Left = 7 - Height = 48 - Top = 8 - Width = 48 - end - object LblTitle: TLabel - Left = 69 - Height = 29 - Top = 16 - Width = 158 - Caption = 'BIFF Explorer' - Font.CharSet = ANSI_CHARSET - Font.Color = clNavy - Font.Height = -24 - Font.Name = 'Arial' - Font.Pitch = fpVariable - Font.Quality = fqDraft - Font.Style = [fsBold] - ParentColor = False - ParentFont = False - end - object BtnClose: TButton - Left = 559 - Height = 29 - Top = 16 - Width = 75 - Anchors = [akTop, akRight] - Cancel = True - Caption = 'Close' - Default = True - ModalResult = 1 - TabOrder = 0 - end - end - object Bevel1: TBevel - Left = 0 - Height = 6 - Top = 66 - Width = 642 - Align = alTop - Shape = bsTopLine - end -end diff --git a/components/fpspreadsheet/reference/BIFFExplorer/beabout.pas b/components/fpspreadsheet/reference/BIFFExplorer/beabout.pas deleted file mode 100644 index 105422b7c..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/beabout.pas +++ /dev/null @@ -1,153 +0,0 @@ -unit beAbout; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, IpHtml, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, - ExtCtrls, StdCtrls; - -type - - { TAboutForm } - - TAboutForm = class(TForm) - Bevel1: TBevel; - BtnClose: TButton; - IconImage: TImage; - LblTitle: TLabel; - Panel1: TPanel; - procedure FormCreate(Sender: TObject); - procedure HTMLViewerHotClick(Sender: TObject); - private - { private declarations } - FHTMLViewer: TIpHtmlPanel; - function CreateCredits: String; - public - { public declarations } - end; - -var - AboutForm: TAboutForm; - -implementation - -{$R *.lfm} - -uses - LCLIntf, types, beHTML; - -{ TAboutForm } - -function TAboutForm.CreateCredits: String; -var - html: THTMLDocument; - clrs: THeaderColors = (clBlack, clBlack, clBlack, clBlack, clBlack); -begin - html := THTMLDocument.Create; - try - clrs[h3] := LblTitle.Font.Color; - clrs[h4] := LblTitle.Font.Color; - with html do begin - BeginDocument('Credits', clrs, false); - AddHeader(h3, 'Credits'); - AddHeader(h4, 'Libraries'); - BeginBulletList; - AddListItem(Hyperlink( - 'Free Pascal', - 'www.freepascal.org') - ); - AddListItem(Hyperlink( - 'Lazarus', - 'www.lazarus.freepascal.org') - ); - AddListItem(HyperLink( - 'fpspreadsheet', - 'http://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/fpspreadsheet/') - ); - AddListItem(Hyperlink( - 'KControls', - 'http://www.tkweb.eu/en/delphicomp/kcontrols.html') - ); - EndBulletList; - - AddEmptyLine; - - AddHeader(h4, 'Icons'); - BeginBulletList; - AddListItem(HyperLink( - 'Fugue icons', - 'http://p.yusukekamiyamane.com/') - + ' (for toolbar icons)'); - AddListItem(HyperLink( - 'Nuvola icons', - 'www.icon-king.com/projects/nuvola/') + - ' (for application icon'); - EndBulletList; - - AddEmptyLine; - - AddHeader(h4, 'Used documentation'); - BeginBulletList; - AddListItem(Hyperlink( - 'OpenOffice.org''s Documentation of the Microsoft Excel File Format', - 'http://www.openoffice.org/sc/excelfileformat.pdf') + - ' (see folder "fpspreadsheet/reference")' - ); - AddListItem(Hyperlink( - '[MS-XLS]: Excel Binary File Format (.xls) Structure', - 'http://msdn.microsoft.com/en-us/library/cc313154%28v=office.12%29.aspx' - )); - AddListItem(HyperLink( - 'Excel97-2007BinaryFileFormat(xls)Specification', - 'http://download.microsoft.com/download/0/B/E/0BE8BDD7-E5E8-422A-ABFD-4342ED7AD886/Excel97-2007BinaryFileFormat(xls)Specification.pdf' - )); - EndBulletList; - - AddEmptyLine; - - EndDocument; - - Result := Lines.Text; - end; - finally - html.Free; - end; -end; - - -procedure TAboutForm.FormCreate(Sender: TObject); -var - ico: TIcon; - sz: TSize; -begin - ico := TIcon.Create; - try - ico.Assign(Application.Icon); - sz.cx := 48; - sz.cy := 48; - ico.Current := ico.GetBestIndexForSize(sz); - IconImage.Picture.Assign(ico); - finally - ico.Free; - end; - - FHTMLViewer := TIpHtmlPanel.Create(self); - FHTMLViewer.Parent := self; - FHTMLViewer.Align := alClient; - FHTMLViewer.DefaultFontSize := 9; - FHTMLViewer.OnHotClick := @HTMLViewerHotClick; - - FHTMLViewer.SetHTMLFromStr(CreateCredits); -end; - - -procedure TAboutForm.HTMLViewerHotClick(Sender: TObject); -begin - OpenURL((Sender as TIpHtmlPanel).HotURL); -end; - - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/bebiffgrid.pas b/components/fpspreadsheet/reference/BIFFExplorer/bebiffgrid.pas deleted file mode 100644 index 686c53c3a..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/bebiffgrid.pas +++ /dev/null @@ -1,6699 +0,0 @@ -unit beBIFFGrid; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, Controls, Grids, fpstypes, fpspreadsheet, beTypes; - -type - TBIFFBuffer = array of byte; - - TBIFFDetailsEvent = procedure(Sender: TObject; ADetails: TStrings) of object; - - TRichTextFormattingRun = packed record - FirstIndex, FontIndex: Word; - end; - TRichTextFormattingRuns = array of TRichTextFormattingRun; - - TBIFFGrid = class(TStringGrid) - private - FRecType: Word; - FBuffer: TBIFFBuffer; - FBufferIndex: LongWord; - FFormat: TsSpreadsheetFormat; - FInfo: Integer; - FTotalSST: Integer; - FCounterSST: Integer; - FPendingCharCount: Integer; - FCurrRow: Integer; - FDetails: TStrings; - FOnDetails: TBIFFDetailsEvent; - function GetStringType: String; - - procedure ShowBackup; - procedure ShowBlankCell; - procedure ShowBOF; - procedure ShowBookBool; - procedure ShowBoolCell; - procedure ShowBottomMargin; - procedure ShowCalcCount; - procedure ShowCalcMode; - procedure ShowCellAddress; - procedure ShowCellAddressRange(AFormat: TsSpreadsheetFormat); - procedure ShowClrtClient; - procedure ShowCodePage; - procedure ShowColInfo; - procedure ShowColWidth; - procedure ShowContinue; - procedure ShowCountry; - procedure ShowDateMode; - procedure ShowDBCell; - procedure ShowDefColWidth; - procedure ShowDefinedName; - procedure ShowDefRowHeight; - procedure ShowDelta; - procedure ShowDimensions; - procedure ShowDSF; - procedure ShowEOF; - procedure ShowExcel9File; - procedure ShowExternBook; - procedure ShowExternCount; - procedure ShowExternSheet; - procedure ShowFileSharing; - procedure ShowFnGroupCount; - procedure ShowFont; - procedure ShowFontColor; - procedure ShowFooter; - procedure ShowFormat; - procedure ShowFormatCount; - procedure ShowFormula; - procedure ShowFormulaTokens(ATokenBytes: Integer); - procedure ShowGCW; - procedure ShowHeader; - procedure ShowHideObj; - procedure ShowHyperLink; - procedure ShowHyperLinkTooltip; - procedure ShowInteger; - procedure ShowInterfaceEnd; - procedure ShowInterfaceHdr; - procedure ShowIteration; - procedure ShowIXFE; - procedure ShowLabelCell; - procedure ShowLabelSSTCell; - procedure ShowLeftMargin; - procedure ShowMergedCells; - procedure ShowMMS; - procedure ShowMSODrawing; - procedure ShowMulBlank; - procedure ShowMulRK; - procedure ShowNote; - procedure ShowNumberCell; - procedure ShowObj; - procedure ShowPageSetup; - procedure ShowPalette; - procedure ShowPane; - procedure ShowPassword; - procedure ShowPrecision; - procedure ShowPrintGridLines; - procedure ShowPrintHeaders; - procedure ShowProt4Rev; - procedure ShowProt4RevPass; - procedure ShowProtect; - procedure ShowRecalc; - procedure ShowRefMode; - procedure ShowRefreshAll; - procedure ShowRightMargin; - procedure ShowRK; - procedure ShowRString; - procedure ShowRow; - procedure ShowSelection; - procedure ShowSharedFormula; - procedure ShowSheet; - procedure ShowSheetPR; - procedure ShowSST; - procedure ShowStandardWidth; - procedure ShowString; - procedure ShowStyle; - procedure ShowStyleExt; - procedure ShowTabID; - procedure ShowTopMargin; - procedure ShowTXO; - procedure ShowWindow1; - procedure ShowWindow2; - procedure ShowWindowProtect; - procedure ShowWriteAccess; - procedure ShowWriteProt; - procedure ShowXF; - procedure ShowXFCRC; - procedure ShowXFEXT; - - protected - procedure Click; override; - procedure DoExtractDetails; - function DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean; override; - function DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean; override; - procedure ExtractString(ABufIndex: Integer; AUnicode: Boolean; - ACharCount: Integer; out AString: String; out ANumbytes: Integer); overload; - procedure ExtractString(ABufIndex: Integer; ALenBytes: Byte; AUnicode: Boolean; - out AString: String; out ANumBytes: Integer; - out ARichTextRuns: TRichTextFormattingRuns; - out ABufIndexOfFirstRichTextRun: LongWord; - IgnoreCompressedFlag: Boolean = false); overload; - procedure ExtractString(ABufIndex: Integer; ALenbytes: Byte; AUnicode: Boolean; - out AString: String; out ANumBytes: Integer; - IgnoreCompressedFlag: Boolean=False); overload; - procedure PopulateGrid; - procedure ShowInRow(var ARow: Integer; var AOffs: LongWord; ASize: Word; - AValue,ADescr: String; ADescrOnly: Boolean = false); - procedure ShowRowColData(var ABufIndex: LongWord); - - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - procedure SetBIFFNodeData(AData: PBIFFNodeData; ABuffer: TBIFFBuffer; - AFormat: TsSpreadsheetFormat); - - published - property TabOrder; - property OnDetails: TBIFFDetailsEvent read FOnDetails write FOnDetails; - property OnSelection; - end; - -implementation - -uses - StrUtils, Math, lazutf8, - fpsutils, - beBIFFUtils; - -const - ABS_REL: array[boolean] of string = ('abs', 'rel'); - -constructor TBIFFGrid.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - ColCount := 4; - FixedCols := 0; - RowCount := 2; - Cells[0, 0] := 'Offset'; - Cells[1, 0] := 'Size'; - Cells[2, 0] := 'Value'; - Cells[3, 0] := 'Description'; - ColWidths[0] := 60; - ColWidths[1] := 60; - ColWidths[2] := 120; - ColWidths[3] := 350; - Options := Options - + [goThumbTracking, goColSizing, goTruncCellHints, goCellHints] - - [goVertLine, goSmoothScroll]; - MouseWheelOption := mwGrid; - FDetails := TStringList.Create; - FPendingCharCount := -1; -end; - - -destructor TBIFFGrid.Destroy; -begin - FDetails.Free; - inherited; -end; - - -procedure TBIFFGrid.Click; -begin - inherited; - if (FBuffer <> nil) then - DoExtractDetails; -end; - - -procedure TBIFFGrid.DoExtractDetails; -begin - if Assigned(FOnDetails) then begin - PopulateGrid; - FOnDetails(self, FDetails); - end; -end; - -function TBIFFGrid.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint - ): Boolean; -begin - Result := inherited; - Click; -end; - -function TBIFFGrid.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint - ): Boolean; -begin - Result := inherited; - Click; -end; - -{ Reads a string character array starting at ABufIndex. The string is supposed - to have ACharCount character, but less characters are read if the string - extends across the max size of a record and is continued in the next CONTINUE - record. - The string is assumed to be a UTF16 string if AUnicode=true, otherwise it is - an ansi string. } -procedure TBIFFGrid.ExtractString(ABufIndex: Integer; AUnicode: Boolean; - ACharCount: Integer; out AString: String; out ANumbytes: Integer); -var - sa: AnsiString; - sw: WideString; - n: Integer; -begin - if AUnicode then // uncompressed unicode --> 2 bytes per char - begin - if ABufIndex + ACharCount * SizeOf(WideChar) >= Length(FBuffer) then - begin - n := (Length(FBuffer) - ABufIndex) div SizeOf(WideChar); - FPendingCharCount := ACharCount - n; // number of chars to be read from subsequent CONTINUE record - end else - begin - n := ACharCount; - FPendingCharCount := 0; - end; - SetLength(sw, n); - ANumBytes := n * SizeOf(WideChar); - Move(FBuffer[ABufIndex], sw[1], ANumBytes); - AString := UTF8Encode(WideStringLEToN(sw)); - end else - begin // ansi or compressed unicode - if ABufIndex + ACharCount >= Length(FBuffer) then - begin - n := Length(FBuffer) - ABufIndex; - FPendingCharCount := ACharCount - n; // number of chars in subsequent CONTINUE record - end else - begin - n := ACharCount; - FPendingCharCount := 0; - end; - SetLength(sa, n); - ANumBytes := n; - Move(FBuffer[ABufIndex], sa[1], ANumBytes); - AString := AnsiToUTF8(sa); // to do: use code page of file - end; -end; - -procedure TBIFFGrid.ExtractString(ABufIndex: Integer; ALenBytes: Byte; AUnicode: Boolean; - out AString: String; out ANumBytes: Integer; - IgnoreCompressedFlag: Boolean = false); -var - rtfRuns: TRichTextFormattingRuns; - rtfIndex: LongWord; -begin - ExtractString(ABufIndex, ALenbytes, AUnicode, AString, ANumBytes, - rtfRuns, rtfIndex, IgnoreCompressedFlag); -end; - -procedure TBIFFGrid.ExtractString(ABufIndex: Integer; ALenBytes: Byte; AUnicode: Boolean; - out AString: String; out ANumBytes: Integer; - out ARichTextRuns: TRichTextFormattingRuns; - out ABufIndexOfFirstRichTextRun: LongWord; - IgnoreCompressedFlag: Boolean = false); -var - ls: Integer; // Character count of string - w: Word; - dw: DWord; - optn: Byte; - n: Integer; // Byte count in string character array - asianPhoneticBytes: DWord; - numRichRuns: Word; - offs: Integer; - rtfBufIndex: Int64; - rtfIndex: Integer; -begin - ABufIndexOfFirstRichTextRun := LongWord(-1); - SetLength(ARichTextRuns, 0); - - if Length(FBuffer) = 0 then begin - AString := ''; - ANumBytes := 0; - exit; - end; - if ALenBytes = 1 then - ls := FBuffer[ABufIndex] - else begin - Move(FBuffer[ABufIndex], w, 2); - ls := WordLEToN(w); - end; - if AUnicode then begin - offs := ALenBytes; - optn := FBuffer[ABufIndex + ALenBytes]; - inc(offs, 1); - - if optn and $08 <> 0 then // rich text - begin - Move(FBuffer[ABufIndex + offs], w, 2); - numRichRuns := WordLEToN(w); - inc(offs, 2); - end else - numRichRuns := 0; - SetLength(ARichTextRuns, numRichRuns); - - if optn and $04 <> 0 then // Asian phonetic - begin - Move(FBuffer[ABufIndex + offs], dw, 4); - AsianPhoneticBytes := DWordLEToN(dw); - inc(offs, 4); - end else - asianPhoneticBytes := 0; - - if (optn and $01 = 0) and (not IgnoreCompressedFlag) then - // compressed --> 1 byte per character - ExtractString(ABufIndex + offs, false, ls, AString, n) - else - // non-compressed unicode - ExtractString(ABufIndex + offs, true, ls, AString, n); - - ANumBytes := offs + n + numRichRuns * 4 + asianPhoneticBytes; - - rtfIndex := 0; - rtfBufIndex := ABufIndex + offs + n; - ABufIndexOfFirstRichTextRun := rtfBufIndex; - while rtfIndex < numRichRuns do begin - Move(FBuffer[rtfBufIndex], w, 2); - ARichTextRuns[rtfIndex].FirstIndex := WordLEToN(w); - Move(FBuffer[rtfBufIndex+2], w, 2); - ARichTextRuns[rtfIndex].FontIndex := WordLEToN(w); - inc(rtfIndex); - inc(rtfBufIndex, 4); - end; - end else - begin - // ansi string - SetLength(ARichTextRuns, 0); // no rich text formatting for ansi strings - ExtractString(ABufIndex + ALenBytes, false, ls, AString, n); - ANumbytes := ALenBytes + n; - end; -end; - - -function TBIFFGrid.GetStringType: String; -begin - case FFormat of - sfExcel2: Result := 'Byte'; - sfExcel5: Result := 'Byte'; - sfExcel8: Result := 'Unicode'; - end; -end; - - -procedure TBIFFGrid.PopulateGrid; -begin - FBufferIndex := 0; - FCurrRow := FixedRows; - FDetails.Clear; - case FRecType of - $0000, $0200: - ShowDimensions; - $0001, $0201: - ShowBlankCell; - $0002: - ShowInteger; - $0003, $0203: - ShowNumberCell; - $0004, $0204: - ShowLabelCell; - $0005, $0205: - ShowBoolCell; - $0006: - ShowFormula; - $0007, $0207: - ShowString; - $0008, $0208: - ShowRow; - $0009, $0209, $0409, $0809: - ShowBOF; - $000A: - ShowEOF; - $000C: - ShowCalcCount; - $000D: - ShowCalcMode; - $000E: - ShowPrecision; - $000F: - ShowRefMode; - $0010: - ShowDelta; - $0011: - ShowIteration; - $0012: - ShowProtect; - $0013: - ShowPassword; - $0014: - ShowHeader; - $0015: - ShowFooter; - $0016: - ShowExternCount; - $0017: - ShowExternSheet; - $0018, $0218: - ShowDefinedName; - $0019: - ShowWindowProtect; - $001C: - ShowNote; - $001D: - ShowSelection; - $001E, $041E: - ShowFormat; - $001F: - ShowFormatCount; - $0022: - ShowDateMode; - $0024: - ShowColWidth; - $0025, $0225: - ShowDefRowHeight; - $0026: - ShowLeftMargin; - $0027: - ShowRightMargin; - $0028: - ShowTopMargin; - $0029: - ShowBottomMargin; - $002A: - ShowPrintHeaders; - $002B: - ShowPrintGridLines; - $0031: - ShowFont; - $003C: - ShowContinue; - $003D: - ShowWindow1; - $003E, $023E: - ShowWindow2; - $0040: - ShowBackup; - $0041: - ShowPane; - $0042: - ShowCodePage; - $0043: - ShowXF; - $0044: - ShowIXFE; - $0045: - ShowFontColor; - $0055: - ShowDefColWidth; - $005B: - ShowFileSharing; - $005C: - ShowWriteAccess; - $005D: - ShowObj; - $005F: - ShowRecalc; - $007D: - ShowColInfo; - $0081: - ShowSheetPR; - $0085: - ShowSheet; - $0086: - ShowWriteProt; - $008C: - ShowCountry; - $008D: - ShowHideObj; - $0092: - ShowPalette; - $099: - ShowStandardWidth; - $00A1: - ShowPageSetup; - $00AB: - ShowGCW; - $00C1: - ShowMMS; - $009C: - ShowFnGroupCount; - $00BE: - ShowMulBlank; - $00BD: - ShowMulRK; - $00D6: - ShowRString; - $00D7: - ShowDBCell; - $00DA: - ShowBookBool; - $00E0: - ShowXF; - $00E1: - ShowInterfaceHdr; - $00E2: - ShowInterfaceEnd; - $00E5: - ShowMergedCells; - $00EC: - ShowMSODrawing; - $00FC: - ShowSST; - $00FD: - ShowLabelSSTCell; - $013D: - ShowTabID; - $0161: - ShowDSF; - $01AE: - ShowExternBook; - $01AF: - ShowProt4Rev; - $01B6: - ShowTXO; - $01B7: - ShowRefreshAll; - $01B8: - ShowHyperlink; - $01BC: - ShowProt4RevPass; - $01C0: - ShowExcel9File; - $027E: - ShowRK; - $0293: - ShowStyle; - $04BC: - ShowSharedFormula; - $0800: - ShowHyperlinkTooltip; - $087C: - ShowXFCRC; - $087D: - ShowXFEXT; - $0892: - ShowStyleExt; - $105C: - ShowClrtClient; - else - RowCount := 2; - Rows[1].Clear; - end; -end; - - -procedure TBIFFGrid.SetBIFFNodeData(AData: PBIFFNodeData; - ABuffer: TBIFFBuffer; AFormat: TsSpreadsheetFormat); -begin - if AData = nil then - exit; - FFormat := AFormat; - FRecType := AData^.RecordID; - FInfo := AData^.Tag; - SetLength(FBuffer, Length(ABuffer)); - if Length(FBuffer) > 0 then - Move(ABuffer[0], FBuffer[0], Length(FBuffer)); - PopulateGrid; - if Assigned(FOnDetails) then FOnDetails(self, FDetails); -end; - - -procedure TBIFFGrid.ShowBackup; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Save backup copy of workbook:'#13); - if w = 0 - then FDetails.Add('0 = no backup') - else FDetails.Add('1 = backup copy is saved when workbook is saved'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'Save backup copy of workbook'); -end; - - -procedure TBIFFGrid.ShowBlankCell; -var - numBytes: Integer; - b: Byte = 0; - w: Word = 0; - dbl: Double; -begin - RowCount := IfThen(FFormat = sfExcel2, FixedRows + 5, FixedRows + 3); - // Offset 0: Row & Offset 2: Column - ShowRowColData(FBufferIndex); - - // Offset 4: Cell attributes (BIFF2) or XF record index (> BIFF2) - if FFormat = sfExcel2 then begin - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell protection and XF index:'#13); - FDetails.Add(Format('Bits 5-0 = %d: XF Index', [b and $3F])); - case b and $40 of - 0: FDetails.Add('Bit 6 = 0: Cell is NOT locked.'); - 1: FDetails.Add('Bit 6 = 1: Cell is locked.'); - end; - case b and $80 of - 0: FDetails.Add('Bit 7 = 0: Formula is NOT hidden.'); - 1: FDetails.Add('Bit 7 = 1: Formula is hidden.'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b, b]), - 'Cell protection and XF index'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Indexes to format and font records:'#13); - FDetails.Add(Format('Bits 5-0 = %d: Index to FORMAT record', [b and $3f])); - FDetails.Add(Format('Bits 7-6 = %d: Index to FONT record', [(b and $C0) shr 6])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b, b]), - 'Indexes of format and font records'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell style:'#13); - case b and $07 of - 0: FDetails.Add('Bits 2-0 = 0: Horizontal alignment is GENERAL'); - 1: FDetails.Add('Bits 2-0 = 1: Horizontal alignment is LEFT'); - 2: FDetails.Add('Bits 2-0 = 2: Horizontal alignment is CENTERED'); - 3: FDetails.Add('Bits 2-0 = 3: Horizontal alignment is RIGHT'); - 4: FDetails.Add('Bits 2-0 = 4: Horizontal alignment is FILLED'); - end; - if b and $08 = 0 - then FDetails.Add('Bit 3 = 0: Cell has NO left border') - else FDetails.Add('Bit 3 = 1: Cell has left black border'); - if b and $10 = 0 - then FDetails.Add('Bit 4 = 0: Cell has NO right border') - else FDetails.Add('Bit 4 = 1: Cell has right black border'); - if b and $20 = 0 - then FDetails.Add('Bit 5 = 0: Cell has NO top border') - else FDetails.Add('Bit 5 = 1: Cell has top black border'); - if b and $40 = 0 - then FDetails.Add('Bit 6 = 0: Cell has NO bottom border') - else FDetails.Add('Bit 6 = 1: Cell has bottom black border'); - if b and $80 = 0 - then FDetails.Add('Bit 7 = 0: Cell has NO shaded background') - else FDetails.Add('Bit 7 = 1: Cell has shaded background'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.2x)', [b,b]), - 'Cell style'); - end else - begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrROw, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Index of XF record'); - end; -end; - - -procedure TBIFFGrid.ShowBOF; -var - numBytes: Integer; - w: Word; - s: String; -begin - case FFormat of - sfExcel2: RowCount := FixedRows + 2; - { //Excel3 & 4 not supported by fpspreadsheet - sfExcel3, sfExcel4: RowCount := FixedRows + 3; - } - sfExcel5: RowCount := FixedRows + 4; - sfExcel8: RowCount := FixedRows + 6; - end; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('BIFF version:'#13); - case FRecType of - $0009, - $0209, - $0409: FDetails.Add('not used'); - $0809: case FFormat of - sfExcel5: FDetails.Add('$0500 = BIFF5'); - sfExcel8: FDetails.Add('$0600 = BIFF8'); - end; - else case w of - $0000: FDetails.Add('$0000 = BIFF5'); - $0200: FDetails.Add('$0200 = BIFF2'); - $0300: FDetails.Add('$0300 = BIFF3'); - $0400: FDetails.Add('$0400 = BIFF4'); - $0500: FDetails.Add('$0500 = BIFF5'); - $0600: FDetails.Add('$0600 = BIFF8'); - end; - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'BIFF version'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - s := '$0010=Sheet, $0020=Chart, $0040=Macro sheet'; - if FFormat > sfExcel2 then - s := '$0005=WB globals, $0006=VB module, ' + s + ', $0100=Workspace'; - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Type of data:'#13); - FDetails.Add(Format('$%.4x = %s', [w, BofName(w)])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - Format('Type of data (%s)', [s])); - - if FFormat > sfExcel2 then begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - { Excel3/4 not supported in fpSpreadsheet - if FFormat in [sfExcel3, sfExcel4] then - ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(WordLEToN(w)), - 'not used') - else} - begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Build identifier (must not be zero)'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Build year (must not be zero)'); - end; - end; - - if FFormat = sfExcel8 then begin - numBytes := 4; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'File history flags'); - - numBytes :=4; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Lowest Excel version that can read all records of this file'); - end; -end; - - -procedure TBIFFGrid.ShowBookBool; -var - numbytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Some properties assosciated with notebook:'#13); - if w and $0001 = 0 - then FDetails.Add('Bit 0 = 0: External link values are saved.') - else FDetails.Add('Bit 0 = 1: External link values are NOT saved.'); - FDetails.Add('Bit 1: to be ignored'); - if w and $0004 = 0 - then FDetails.Add('Bit 2 = 0: Workbook does not have a mail envelope') - else FDetails.Add('Bit 2 = 1: Workbook has a mail envelope'); - if w and $0008 = 0 - then FDetails.Add('Bit 3 = 0: Mail envelope is NOT visible.') - else FDetails.Add('Bit 3 = 1: Mail envelope is visible.'); - if w and $0010 = 0 - then FDetails.Add('Bit 4 = 0: Mail envelope has NOT been initialized.') - else FDetails.Add('Bit 4 = 1: Mail envelope has been initialized.'); - case (w and $0060) shr 5 of - 0: FDetails.Add('Bits 5-6 (Update external links) = 0: Prompt user to update'); - 1: FDetails.Add('Bits 5-6 (Update external linls) = 1: Do not update, and do not prompt user.'); - 2: FDetails.Add('Bits 5-6 (Update external links) = 2: Silently update external links.'); - end; - FDetails.Add('Bit 7: undefined, must be ignored'); - if w and $0100 = 0 - then FDetails.Add('Bit 8 = 0: Do not hide borders of tables that do not contain the active cell') - else FDetails.Add('Bit 8 = 1: Hide borders of tables that do not contain the active cell'); - FDetails.Add('Bits 9-15: MUST BE zero, MUST be ignored'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), - 'Specifies some properties assosciated with a workbook'); -end; - -procedure TBIFFGrid.ShowBoolCell; -var - numBytes: Integer; - w: Word; - b: Byte; -begin - if FFormat = sfExcel2 then - RowCount := FixedRows + 7 - else - RowCount := FixedRows + 5; - - ShowRowColData(FBufferIndex); - - if FFormat = sfExcel2 then begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Cell protection and XF index:'#13); - FDetails.Add(Format('Bits 5-0 = %d: XF Index', [b and $3F])); - case b and $40 of - 0: FDetails.Add('Bit 6 = 0: Cell is NOT locked.'); - 1: FDetails.Add('Bit 6 = 1: Cell is locked.'); - end; - case b and $80 of - 0: FDetails.Add('Bit 7 = 0: Formula is NOT hidden.'); - 1: FDetails.Add('Bit 7 = 1: Formula is hidden.'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Cell protection and XF index'); - - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Indexes to format and font records:'#13); - FDetails.Add(Format('Bits 5-0 = %d: Index to FORMAT record', [b and $3f])); - FDetails.Add(Format('Bits 7-6 = %d: Index to FONT record', [(b and $C0) shr 6])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Indexes of format and font records'); - - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Cell style:'#13); - case b and $07 of - 0: FDetails.Add('Bits 2-0 = 0: Horizontal alignment is GENERAL'); - 1: FDetails.Add('Bits 2-0 = 1: Horizontal alignment is LEFT'); - 2: FDetails.Add('Bits 2-0 = 2: Horizontal alignment is CENTERED'); - 3: FDetails.Add('Bits 2-0 = 3: Horizontal alignment is RIGHT'); - 4: FDetails.Add('Bits 2-0 = 4: Horizontal alignment is FILLED'); - end; - if b and $08 = 0 - then FDetails.Add('Bit 3 = 0: Cell has NO left border') - else FDetails.Add('Bit 3 = 1: Cell has left black border'); - if b and $10 = 0 - then FDetails.Add('Bit 4 = 0: Cell has NO right border') - else FDetails.Add('Bit 4 = 1: Cell has right black border'); - if b and $20 = 0 - then FDetails.Add('Bit 5 = 0: Cell has NO top border') - else FDetails.Add('Bit 5 = 1: Cell has top black border'); - if b and $40 = 0 - then FDetails.Add('Bit 6 = 0: Cell has NO bottom border') - else FDetails.Add('Bit 6 = 1: Cell has bottom black border'); - if b and $80 = 0 - then FDetails.Add('Bit 7 = 0: Cell has NO shaded background') - else FDetails.Add('Bit 7 = 1: Cell has shaded background'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.2x)', [b,b]), - 'Cell style'); - end else - begin // BIFF3 - BIFF 8 - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrROw, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Index of XF record'); - end; - - // boolean value - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, - Format('%d (%s)', [b, Uppercase(BoolToStr(Boolean(b), true))]), - 'Boolean value (0=FALSE, 1=TRUE)' - ); - - // bool/error flag - numBytes := 1; - b := FBuffer[FBufferIndex]; - if b = 0 then - ShowInRow(FCurrRow, FBufferIndex, numbytes, '0 (boolean value)', - 'Boolean/Error value flag (0=boolean, 1=error value)') - else - ShowInRow(FCurrRow, FBufferIndex, numbytes, '1 (error value)', - 'Boolean/Error value flag (0=boolean, 1=error value)'); -end; - -procedure TBIFFGrid.ShowBottomMargin; -var - numBytes: Integer; - dbl: Double; -begin - RowCount := FixedRows + 1; - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl), - 'Bottom page margin in inches (IEEE 754 floating-point value, 64-bit double precision)'); -end; - - -procedure TBIFFGrid.ShowCalcCount; -var - numBytes: Word; - w: Word; -begin - RowCount := FixedRows + 1; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Maximum number of iterations allowed in circular references'); -end; - - -procedure TBIFFGrid.ShowCalcMode; -var - numBytes: Word; - w: word; - s: String; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if w = $FFFF then - s := '–1 = automatically except for multiple table operations' - else if w = 0 then - s := '0 = manually' - else if w = 1 then - s := '1 = automatically (default)'; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), s); -end; - - -procedure TBIFFGrid.ShowCellAddress; -{ Note: The bitmask assignment to relative column/row is reversed in relation - to OpenOffice documentation in order to match with Excel files. } -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 column index') - else FDetails.Add('Bit 14=1: relative column index'); - if c and $8000 = 0 - then FDetails.Add('Bit 15=0: absolute row index') - else FDetails.Add('Bit 15=1: relative row 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 column index') - else FDetails.Add('Bit 14=1: relative column index'); - if r and $8000 = 0 - then FDetails.Add('Bit 15=0: absolute row index') - else FDetails.Add('Bit 15=1: relative row 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(AFormat: TsSpreadsheetFormat); -{ Note: The bitmask assignment to relative column/row is reversed in relation - to OpenOffice documentation in order to match with Excel files. - - The spreadsheet format is passed as a parameter because some BIFF8 records - used these fields in BIFF5 format. } -var - numbytes: Word; - b: Byte; - w: Word; - r, c, r2, c2: Integer; - s: String; -begin - if AFormat = 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 column index') - else FDetails.Add('Bit 14=1: relative column index'); - if c and $8000 = 0 - then FDetails.Add('Bit 15=0: absolute row index') - else FDetails.Add('Bit 15=1: relative row 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 column index') - else FDetails.Add('Bit 14=1: relative column index'); - if c2 and $8000 = 0 - then FDetails.Add('Bit 15=0: absolute row index') - else FDetails.Add('Bit 15=1: relative row 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 column index') - else FDetails.Add('Bit 14=1: relative column index'); - if r and $8000 = 0 - then FDetails.Add('Bit 15=0: absolute row index') - else FDetails.Add('Bit 15=1: relative row 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 column index') - else FDetails.Add('Bit 14=1: relative column index'); - if r2 and $8000 = 0 - then FDetails.Add('Bit 15=0: absolute row index') - else FDetails.Add('Bit 15=1: relative row 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; -var - w: Word; - dw: DWord; - numbytes: Word; -begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - - RowCount := FixedRows + w + 1; - - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Number of colors (must be 3)'); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [dw]), - 'Foreground color (system window text color)'); - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [dw]), - 'Background color (system window color)'); - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [dw]), '???'); -end; - - -procedure TBIFFGrid.ShowCodePage; -var - numBytes: Word; - w: Word; - s: String; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - s := CodePageName(w); - if Row = FCurrRow then begin - FDetails.Add('Code page:'#13); - FDetails.Add(Format('$%.04x = %s', [w, s])); - end; - if s <> '' then s := 'Code page identifier (' + s + ')' else s := 'Code page identifier'; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), s); -end; - - -procedure TBIFFGrid.ShowColInfo; -var - numBytes: Integer; - w: Word; -begin - if FFormat = sfExcel2 then - exit; - - RowCount := FixedRows + 5; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index of first column in range'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index of last column in range'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d (%f characters)', [w, w/256]), - 'Width of the columns in 1/256 of the width of the zero character, using default font (first FONT record in the file)'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to XF record for default column formatting'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Column options:'#13); - if w and $0001 = 0 - then FDetails.Add('Bit $0001 = 0: Columns are NOT hidden') - else FDetails.Add('Bit $0001 = 1: Columns are hidden'); - FDetails.Add(Format('Bits $0700 = %d: Outline level of the columns (0 = no outline)', [(w and $0700) shr 8])); - if w and $1000 = 0 - then FDetails.Add('Bit $1000 = 0: Columns are NOT collapsed') - else FDetails.Add('Bit $1000 = 1: Columns are collapsed'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), 'Option flags'); -end; - - -procedure TBIFFGrid.ShowColWidth; -var - numBytes: Integer; - w: Word; - b: Byte; -begin - if FFormat <> sfExcel2 then - exit; - - RowCount := FixedRows + 3; - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Index of first column'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Index of last column'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Width of the columns in 1/256 of the width of the zero character, using default font (first FONT record in the file)'); -end; - - -procedure TBIFFGrid.ShowContinue; -var - numbytes: Integer; - s: String; - sa: ansistring; - sw: widestring; - ls: Integer; - i, j: Integer; - w: Word; - n: Integer; - run: Integer; - total2: Integer; - optn: Byte; - rtfRuns: TRichTextFormattingRuns; - rtfBufferIndex: LongWord; -begin - case FInfo of - BIFFNODE_TXO_CONTINUE1: - begin - RowCount := FixedRows + 1; - numbytes := Length(FBuffer); - if FBuffer[FBufferIndex] = 0 then begin - ls := Length(FBuffer)-1; - SetLength(sa, ls); - Move(FBuffer[FBufferIndex+1], sa[1], ls); - s := AnsiToUTF8(sa); - end else - if FBuffer[FBufferIndex] = 1 then begin - ls := (Length(FBuffer) - 1) div SizeOf(WideChar); - SetLength(sw, ls); - Move(FBuffer[FBufferIndex+1], sw[1], ls*SizeOf(WideChar)); - s := UTF8Encode(sw); - end else - s := 'ERROR!!!'; - s := UTF8StringReplace(s, #$0A, '[/n]', [rfReplaceAll]); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Comment text'); - end; - - BIFFNODE_TXO_CONTINUE2: - begin - RowCount := FixedRows + 1000; - n := 0; - numBytes := 2; - run := 1; - while FBufferIndex < Length(FBuffer) - 4*SizeOf(Word) do begin - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), Format( - 'Run %d: Index of first character using this font (0-based)', [run])); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToSTr(WordLEToN(w)), - Format('Run %d: Index to FONT record', [run])); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInrow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Not used'); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInrow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Not used'); - inc(n); - - inc(run); - end; - - // lastRun - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInrow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Number of characters'); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInrow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Not used'); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInrow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Not used'); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Not used'); - inc(n); - - RowCount := FixedRows + n; - end; - - BIFFNODE_SST_CONTINUE: - begin // Continues an SST record - if FPendingCharCount = -1 then - begin - RowCount := FixedRows + 1; - ShowInRow(FCurrRow, FBufferIndex, 0, '', 'Please select preceding SST record first.'); - exit; - end; - - RowCount := FixedRows + FTotalSST; - n := 0; - - optn := FBuffer[FBufferIndex]; - if optn and $01 = $01 then // wide characters - ExtractString(FBufferIndex+1, true, FPendingCharCount, s, numBytes) - else - ExtractString(FBufferIndex+1, false, FPendingCharCount, s, numbytes); - FPendingCharCount := -1; - inc(numbytes, 1); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, Format('Shared String #%d (rest)', [FCounterSST])); - inc(n); - - FPendingCharCount := -1; - - for i:=FCounterSST+1 to FTotalSST do - begin - FCounterSST := i; - ExtractString(FBufferIndex, 2, true, s, numBytes, rtfRuns, rtfBufferIndex); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, Format('Shared string #%d', [i])); - inc(n); - if Length(rtfRuns) > 0 then begin - numBytes := 2; - for j:=0 to High(rtfRuns) do - begin - ShowInRow(FCurrRow, rtfBufferIndex, 2, IntToStr(rtfRuns[j].FirstIndex), - Format('Rich-Text formatting run #%d, index of first character', [j])); - ShowInRow(FCurrRow, rtfBufferIndex, 2, IntToStr(rtfRuns[j].FontIndex), - Format('Rich-Text formatting run #%d, font index', [j])); - inc(n, 2); - end; - end; - if FPendingCharCount > 0 then - begin - FInfo := BIFFNODE_SST_CONTINUE; - break; - end; - end; - RowCount := FixedRows + n; - if FPendingCharCount = 0 then - FPendingCharCount := -1; - end; - end; -end; - - -procedure TBIFFGrid.ShowCountry; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 2; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Windows country identifier for UI language of Excel'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Windows country identifier of system regional settings'); -end; - - -procedure TBIFFGrid.ShowDateMode; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - '0 = Base date is 1899-Dec-31, 1 = Base date is 1904-Jan-01'); -end; - -procedure TBIFFGrid.ShowDBCell; -var - i, n: Integer; - dw: DWord; - w: Word; - numBytes: Integer; -begin - if FFormat < sfExcel5 then exit; - - n := (Length(FBuffer) - 4) div 2; - RowCount := FixedRows + 1 + n; - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), - 'Relative offset to first ROW record in the Row Block'); - - numBytes := 2; - for i:=1 to n do begin - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Relative offsets to calculate stream position of the first cell record in row'); - end; -end; - -procedure TBIFFGrid.ShowDefColWidth; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Column width in characters, using the width of the zero character from default '+ - 'font (first FONT record in the file) + some extra space.'); -end; - - -procedure TBIFFGrid.ShowDefinedName; -var - numBytes: Integer; - b: Byte; - w: Word; - isFuncMacro: Boolean; - lenName: Word; - ansistr: AnsiString; - widestr: WideString; - s: String; - macro: Boolean; - formulaSize: Word; - firstTokenBufIdx: Integer; - token: Byte; - r,c, r2,c2: Integer; - builtinName: Boolean; -begin - BeginUpdate; - RowCount := FixedRows + 1000; - // Brute force simplification because of unknown row count at this point - // Will be reduced at the end. - - builtinName := false; - if FFormat = sfExcel2 then - begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - isFuncMacro := b and $02 <> 0; - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if b and $02 = 0 then - FDetails.Add(' Bit $02 = 0: NO function macro or command macro') - else - FDetails.Add('* Bit $02 = 1: Function macro or command macro'); - if b and $04 = 0 then - FDetails.Add(' Bit $04 = 0: NO Complex function (array formula or user defined)') - else - FDetails.Add('* Bit $04 = 1: Complex function (array formula or user defined)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), - 'Option flags'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - if isFuncMacro then - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - '$01 = Function macro, $02 = Command macro') - else - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'unknown'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Keyboard shortcut (only for command macro names)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Length of the name (character count)'); - lenName := b; - - numbytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(b), - 'Size of the formula data'); - formulaSize := b; - end - else - begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - macro := (w and $0008 <> 0); - builtinName := (w and $0020 <> 0); - FDetails.Add('Option flags:'#13); - if w and $0001 = 0 - then FDetails.Add(' Bit $0001 (flag name "hidden") = 0: Visible') - else FDetails.Add('* Bit $0001 (flag name "hidden")= 1: Hidden'); - if w and $0002 = 0 - then FDetails.Add(' Bit §0002 (flag name "func") = 0: Command macro') - else FDetails.Add('* Bit $0002 (flag name "func") = 1: Function macro'); - if w and $0004 = 0 - then FDetails.Add(' Bit $0004 (flag name "vbasic") = 0: Sheet macro') - else FDetails.Add('* Bit $0004 (flag name "vbasic") = 1: Visual basic macro'); - if w and $0008 = 0 - then FDetails.Add(' Bit $0008 (flag name "macro") = 0: Standard name') - else FDetails.Add('* Bit $0008 (flag name "macro") = 1: Macro name'); - if w and $0010 = 0 - then FDetails.Add(' Bit $0010 (flag name "complex") = 0: Simple formula') - else FDetails.Add('* Bit $0010 (flag name "complex") = 1: Complex formula (array formula or user defined)'); - if w and $0020 = 0 - then FDetails.Add(' Bit $0020 (flag name "builtin") = 0: User-defined name') - else FDetails.Add('* Bit $0020 (flag name "builtin") = 1: Built-in name'); - case (w and $0FC0) shr 6 of - 0: if macro then - FDetails.Add(' Bit $0FC0 = 0: --- forbidden value, must be > 0 ---') - else - FDetails.Add(' Bit $0FC0 (flag name "funcgroup") = 0: not used (requires "macro" = 1)'); - 1: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 1: financial'); - 2: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 2: date & time'); - 3: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 3: math & trig'); - 4: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 4: statistical'); - 5: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 5: lookup & reference'); - 6: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 6: database'); - 7: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 7: text'); - 8: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 8: logical'); - 9: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 9: information'); - 10: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 10: commands'); - 11: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 11: customizing'); - 12: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 12: macro control'); - 13: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 13: dde/external'); - 14: FDetails.Add('* Bit $0FC0 (flag name "funcgroup") = 14: user defined'); - end; - if w and $1000 = 0 - then FDetails.Add(' Bit $1000 (flag name "binary") = 0: formula definition') - else FDetails.add('* Bit $1000 (flag name "binary") = 1: binary data (BIFF5-BIFF8)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Option flags'); - - numbytes := 1; - b := FBuffer[FBufferIndex]; - ShowInrow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b, b]), - 'Keyboard shortcurt (only for command macro names)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - 'Length of the name (character count)'); - lenName := b; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Size of the formula data'); - formulaSize := w; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if FFormat = sfExcel5 then - ShowInRow(FCurrRow, FBufferIndex, NumBytes, IntToStr(w), - '0 = Global name, otherwise index to EXTERNSHEET record (one-based)') - else - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'not used'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, NumBytes, IntToStr(w), - '0 = Global name, otherwise index to sheet (one-based)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, nuMbytes, IntToStr(b), - 'Length of the menu text (character count)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, nuMbytes, IntToStr(b), - 'Length of the description text (character count)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, nuMbytes, IntToStr(b), - 'Length of the help topic text (character count)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, nuMbytes, IntToStr(b), - 'Length of the status bar text (character count)'); - - if FFormat = sfExcel5 then begin - numBytes := lenName * sizeOf(ansiChar); - SetLength(ansiStr, lenName); - Move(FBuffer[FBufferIndex], ansiStr[1], numbytes); - s := AnsiToUTF8(ansistr); - end else - begin - if (FBuffer[FBufferIndex] and $01 = 0) //and (not IgnoreCompressedFlag) - then begin // compressed --> 1 byte per character - SetLength(ansiStr, lenName); - numbytes := lenName*SizeOf(ansiChar) + 1; - Move(FBuffer[FBufferIndex + 1], ansiStr[1], lenName*SizeOf(AnsiChar)); - s := AnsiToUTF8(ansiStr); - end else begin - SetLength(wideStr, lenName); - numBytes := lenName*SizeOf(WideChar) + 1; - Move(FBuffer[FBufferIndex + 1], wideStr[1], lenName*SizeOf(WideChar)); - s := UTF8Encode(WideStringLEToN(wideStr)); - end; - end; - if builtinName and (Length(s) = 1) then begin - s := Format('%s ($%x --> ', [s, ord(s[1])]); - case ord(s[1]) of - 0: s := s + 'Consolidate_Area)'; - 1: s := s + 'Auto_Open)'; - 2: s := s + 'Auto_Close)'; - 3: s := s + 'Extract)'; - 4: s := s + 'Database)'; - 5: s := s + 'Citeria)'; - 6: s := s + 'Print_Area)'; - 7: s := s + 'Print_Titles)'; - 8: s := s + 'Recorder)'; - 9: s := s + 'Data_Form)'; - 10: s := s + 'Auto_Activate)'; - 11: s := s + 'Auto_Deactivate)'; - 12: s := s + 'Sheet_Title)'; - 13: s := s + '_FilterDatabase)'; - else s := s + 'unknown meaning)'; - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Name (Unicode string without length field)'); - end; - - firstTokenBufIdx := FBufferIndex; - while FBufferIndex < firstTokenBufIdx + formulaSize do begin - token := FBuffer[FBufferIndex]; - numBytes := 1; - case token of - $10: - begin - numBytes := 1; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tList (List operator)'); - end; - - $29, $39, $49: - begin - case token of - $29: s := 'Token tMemFuncR'; - $39: s := 'Token tMemFuncV'; - $49: s := 'Token tMemFuncV'; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [token]), s); - if FFormat = sfExcel2 then - begin - numbytes := 1; - b := FBuffer[FBufferIndex]; - w := b; - end else - begin - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Size of following subexpression (ends after offset ' + IntToStr(FBufferIndex+w-1+numbytes) + ')'); - end; - - $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)), - 'negative --> 3D reference, 1-based index to EXTERNSHEET record = ' + IntToStr(-SmallInt(w))); - numBytes := 8; - ShowInRow(FCurrRow, FBufferIndex, numBytes, '', 'Not used'); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Zero-based index to first referenced sheet ($FFFF = deleted sheet)'); - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Zero-based 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(FFormat); // Cell range - end; - - else - numBytes := 1; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - '(unknown token)'); - end; // case - end; // while - - RowCount := FCurrRow; - EndUpdate(true); -end; - -procedure TBIFFGrid.ShowDefRowHeight; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + IfThen(FFormat = sfExcel2, 1, 2); - - if FFormat = sfExcel2 then begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Default height for unused rows:'#13); - FDetails.Add(Format( - 'Bits $7FFF = %d: Default height for unused rows, in twips = 1/20 of a point', - [w and $7FFF])); - if w and $8000 = 0 then - FDetails.Add('Bit $8000 = 0: Row height changed manually') - else - FDetails.Add('Bit $8000 = 1: Row height not changed manually'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Default height for unused rows, in twips = 1/20 of a point'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if w and $0001 = 0 - then FDetails.Add('Bit $0001 = 0: Row height and default font height do match') - else FDetails.Add('Bit $0001 = 1: Row height and default font height do not match'); - if w and $0002 = 0 - then FDetails.Add('Bit $0002 = 0: Row is visible') - else FDetails.Add('Bit $0002 = 1: Row is hidden'); - if w and $0004 = 0 - then FDetails.Add('Bit $0004 = 0: No additional space above the row') - else FDetails.Add('Bit $0004 = 1: Additional space above the row'); - if w and $0008 = 0 - then FDetails.Add('Bit $0008 = 0: No additional space below the row') - else FDetails.Add('Bit $0008 = 1: Additional space below the row'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [WordLEToN(w)]), - 'Option flags'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Default height for unused rows, in twips = 1/20 of a point'); - end; -end; - - -procedure TBIFFGrid.ShowDelta; -var - numBytes: Integer; - dbl: Double; -begin - RowCount := FixedRows + 1; - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl), - 'Maximum change in iteration (IEEE 754 floating-point value, 64-bit double precision)'); -end; - - -procedure TBIFFGrid.ShowDimensions; -var - numBytes: Integer; - dw: DWord; - w: Word; -begin - RowCount := FixedRows + IfThen(FFormat = sfExcel2, 4, 5); - - if FFormat = sfExcel8 then begin - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)), - 'Index to first used row'); - - Move(FBuffer[FBufferIndex], dw, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(DWordLEToN(dw)), - 'Index to last used row, increased by 1'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to first used row'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to last used row, increased by 1'); - end; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to first used column'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to last used column, increased by 1'); - - if FFormat <> sfExcel2 then begin - numBytes := 2; - ShowInRow(FCurrRow, FBufferIndex, numBytes, '', - '(not used)'); - end; -end; - - -procedure TBIFFGrid.ShowDSF; -var - w: Word; - numbytes: Integer; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), 'Reserved, MUST be ignored'); -end; - - -procedure TBIFFGrid.ShowEOF; -begin - RowCount := FixedRows + 1; - ShowInRow(FCurrRow, FBufferIndex, 0, '', '(no content)'); -end; - - -procedure TBIFFGrid.ShowExcel9File; -begin - RowCount := FixedRows + 1; - ShowInRow(FCurrRow, FBufferIndex, 0, '', 'Optional and unused'); -end; - - -procedure TBIFFGrid.ShowExternBook; -var - numBytes: Integer; - w: Word; - wideStr: WideString; - ansiStr: AnsiString; - s: String; - i, n: Integer; - b: Byte; - rtfRuns: TRichTextFormattingRuns; -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 - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - SetLength(ansiStr, 1); - ansiStr[1] := char((w and $FF00) shr 8); - s := Format('%s (string bytes <#%.2x> <#%.2x>)', [ansistr, w and $00FF, (w and $FF00) shr 8]); - - 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 (Length(s) = 1) and (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 begin - Delete(s, 1, 1); - s := '<#03>' + s; - end; - 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 EXTERNBOOK record', [i])); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - Format('REF #%d: Index to first sheet in EXTERNBOOK sheet list', [i])); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - Format('REF #%d: Index to last sheet in EXTERNBOOK sheet list', [i])); - end; - end; -end; - - -procedure TBIFFGrid.ShowFileSharing; -var - numbytes: Integer; - w: Word; - s: String; -begin - RowCount := FixedRows + 3; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Recommend read-only state when loading the file:'#13); - if w = 0 then FDetails.Add('0 = no') else FDetails.Add('1 = yes'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Recommend read-only state when loading the file'); - - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'Hash value calculated from the read-only password'); - - ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8, - s, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'User name of the file creator' + IfThen(FFormat = sfExcel8, - ' (Unicode string, 16-bit string length)', - ' (byte string, 8-bit string length)' - )); -end; - - -procedure TBIFFGrid.ShowFnGroupCount; -var - numbytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Number of built-in function categories:'#13); - case w of - $000E: - FDetails.Add( - 'There are 14 built-in function categories in the workbook.'#13+ - 'This implies that the file was last saved by a specific version of the application.'#13+ - 'The following 9 built-in function categories are visible to the end-user:'#13+ - ' Financial'#13+ - ' Date & Time'#13+ - ' Math & Trig'#13+ - ' Statistical'#13+ - ' Lookup & Reference'#13+ - ' Database'#13+ - ' Text'#13+ - ' Logical'#13+ - ' Information'#13+ - 'The following 5 built-in function categories are not visible to the end-user:'#13+ - ' UserDefined'#13+ - ' Commands'#13+ - ' Customize'#13+ - ' MacroControl'#13+ - ' DDEExternal' - ); - $0010: - FDetails.Add( - 'There are 16 built-in function categories in the workbook.'#13+ - 'This implies that the file was last saved by a specific version of the application'#13+ - 'The following 11 built-in function categories are visible to the end-user:'#13+ - ' Financial'#13+ - ' Date & time'#13+ - ' Math & Trig'#13+ - ' Statistical'#13+ - ' Lookup & Reference'+ - ' Database'#13+ - ' Text'#13+ - ' Logical'#13+ - ' Information'#13+ - ' Engineering'#13+ - ' Cube'#13+ - 'The following 5 built-in function categories are not visible to the end-user:'#13+ - ' UserDefined'#13+ - ' Commands'#13+ - ' Customize'#13+ - ' MacroControl'#13+ - ' DDEExternal' - ); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Number of built-in function categories'); -end; - - -procedure TBIFFGrid.ShowFont; -var - numbytes: Integer; - w: Word; - b: Byte; - s: String; -begin - RowCount := IfThen(FFormat = sfExcel2, 3, 10) + FixedRows; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d (= %.1gpt)', [w, w/20]), - 'Font height in twips (=1/20 point)'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if w and $0001 = 0 - then FDetails.Add(' Bit $0001 = 0: not bold') - else FDetails.Add('x Bit $0001 = 1: bold (redundant in BIFF5-BIFF8)'); - if w and $0002 = 0 - then FDetails.Add(' Bit $0002 = 0: not italic') - else FDetails.Add('x Bit $0002 = 1: italic'); - if w and $0004 = 0 - then FDetails.Add(' Bit $0004 = 0: not underlined') - else FDetails.Add('x Bit $0004 = 1: underlined (redundant in BIFF5-BIFF8)'); - if w and $0008 = 0 - then FDetails.Add(' Bit $0008 = 0: not struck out') - else FDetails.Add('x Bit $0008 = 1: struck out'); - if w and $0010 = 0 - then FDetails.Add(' Bit $0010 = 0: not outlined') - else FDetails.Add('x Bit $0010 = 1: outlined'); - if w and $0020 = 0 - then FDetails.Add(' Bit $0020 = 0: not shadowed') - else FDetails.Add('x Bit $0020 = 1: shadowed'); - if w and $0040 = 0 - then FDetails.Add(' Bit $0040 = 0: not condensed') - else FDetails.Add('x Bit $0040 = 1: condensed'); - if w and $0080 = 0 - then FDetails.Add(' Bit $0080 = 0: not extended') - else FDetails.Add('x Bit $0080 = 1: extended'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Option flags'); - - if FFormat <> sfExcel2 then begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Color index'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w,w]), - 'Font weight (400=normal, 700=bold)'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Escapement:'#13); - case w of - 0: FDetails.Add('0 = none'); - 1: FDetails.Add('1 = superscript'); - 2: FDetails.Add('2 = subscript'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'Escapement ($00=none, $01=superscript, $02=subscript)'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Underline type:'#13); - case b of - $00: FDetails.Add('$00 = no underline'); - $01: FDetails.Add('$01 = single underline'); - $02: FDetails.Add('$02 = double underline'); - $21: FDetails.Add('$21 = single accounting'); - $22: FDetails.Add('$22 = double accounting'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), - 'Underline type ($00=none, $01=single, $02=double, ...)'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Font family:'#13); - case b of - $00: FDetails.Add('$00 = None (unknown or don''t care)'); - $01: FDetails.Add('$01 = Roman (variable width, serifed)'); - $02: FDetails.Add('$02 = Swiss (variable width, sans-serifed)'); - $03: FDetails.Add('$03 = Modern (fixed width, serifed or sans-serifed)'); - $04: FDetails.Add('$04 = Script (cursive)'); - $05: FDetails.Add('$05 = Decorative (specialised, for example Old English, Fraktur)'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%.2x', [b]), - 'Font family'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - case b of - $00: s := 'ANSI Latin'; - $01: s := 'System default'; - $02: s := 'Symbol'; - $4D: s := 'Apple Roman'; - $80: s := 'ANSI Japanese Shift-JIS'; - $81: s := 'ANSI Korean (Hangul)'; - $82: s := 'ANSI Korean (Johab)'; - $86: s := 'ANSI Chinese Simplified GBK'; - $88: s := 'ANSI Chinese Traditional BIG5'; - $A1: s := 'ANSI Greek'; - $A2: s := 'ANSI Turkish'; - $A3: s := 'ANSI Vietnamese'; - $B1: s := 'ANSI Hebrew'; - $B2: s := 'ANSI Arabic'; - $BA: s := 'ANSI Baltic'; - $CC: s := 'ANSI Cyrillic'; - $DE: s := 'ANSI Thai'; - $EE: s := 'ANSI Latin II (Central European)'; // East Europe in MS docs! - $FF: s := 'OEM Latin I'; - else s := ''; - end; - if s <> '' then s := Format('$%.2x: %s', [b, s]) else s := Format('$%.2x', [b]); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, - 'Character set'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), 'Not used'); - end; - - ExtractString(FBufferIndex, 1, FFormat=sfExcel8, s, numbytes); - if FFormat = sfExcel8 then - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Font name (unicode string, 8-bit string length)') - else - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Font name (byte string, 8-bit string length)'); -end; - - -procedure TBIFFGrid.ShowFontColor; -var - numBytes: Integer; - w: Word; - s: String; -begin - RowCount := FixedRows + 1; - NumBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - case w of - $0000: s := 'EGA Black (rgb = $000000)'; - $0001: s := 'EGA White (rgb = $FFFFFF)'; - $0002: s := 'EGA Red (rgb = $0000FF)'; - $0003: s := 'EGA Green (rgb = $00FF00)'; - $0004: s := 'EGA Blue (rgb = $FF0000)'; - $0005: s := 'EGA Yellow (rgb = $00FFFF)'; - $0006: s := 'EGA Magenta (rgb = $FF00FF)'; - $0007: s := 'EGA Cyan (rgb = $FFFF00)'; - $7FFF: s := 'Automatic (system window text colour)'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.04x)', [w, w]), - Format('Font color index into preceding FONT record (%s)', [s])); -end; - -procedure TBIFFGrid.ShowFooter; -var - numbytes: Integer; - s: String; -begin - RowCount := FixedRows + 1; - if Length(FBuffer) = 0 then - ShowInRow(FCurrRow, FBufferIndex, 0, '', '(empty record)') - else - begin - ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8, - 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; - - -procedure TBIFFGrid.ShowFormat; -var - numBytes: Integer; - w: word; - b: Byte; - s: String; -begin - RowCount := IfThen(FFormat = sfExcel2, FixedRows + 1, FixedRows + 2); - if FFormat <> sfExcel2 then begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'FormatIndex used in other records'); - end; - b := IfThen(FFormat=sfExcel8, 2, 1); - ExtractString(FBufferIndex, b, (FFormat=sfExcel8), s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, - Format('Number format string (%s string, %d-bit string length)', [GetStringType, b*8])); -end; - - -procedure TBIFFGrid.ShowFormatCount; -var - numBytes: Integer; - w: Word; -begin - if FFormat = sfExcel2 then begin - RowCount := 1 + FixedRows; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Number of FORMAT records'); - end; -end; - - -procedure TBIFFGrid.ShowFormula; -var - numBytes: Integer; - b: Byte; - w: Word; - q: QWord; - dbl: double absolute q; - bytearr: array[0..7] of byte absolute q; - wordarr: array[0..3] of word absolute q; -// s: String; - tokenBytes: Integer; -// firstTokenBufIdx: Integer; -// token: Byte; - r,c, r2,c2: Integer; -begin - BeginUpdate; - RowCount := FixedRows + 1000; - // Brute force simplification because of unknown row count at this point - // Will be reduced at the end. - - // Offset 0 = Row, Offset 2 = Column - ShowRowColData(FBufferIndex); - // Offset 4 = Cell attributes (BIFF2) or XF ecord index (> BIFF2) - if FFormat = sfExcel2 then begin - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell protection and XF index:'#13); - FDetails.Add(Format('x Bits 5-0 = %d: XF Index', [b and $3F])); - case b and $40 of - 0: FDetails.Add(' Bit 6 = 0: Cell is NOT locked.'); - 1: FDetails.Add('x Bit 6 = 1: Cell is locked.'); - end; - case b and $80 of - 0: FDetails.Add(' Bit 7 = 0: Formula is NOT hidden.'); - 1: FDetails.Add('x Bit 7 = 1: Formula is hidden.'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Cell protection and XF index'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Indexes to format and font records:'#13); - FDetails.Add(Format('Bits 5-0 = %d: Index to FORMAT record', [b and $3f])); - FDetails.Add(Format('Bits 7-6 = %d: Index to FONT record', [(b and $C0) shr 6])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Indexes of format and font records'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell style:'#13); - case b and $07 of - 0: FDetails.Add('Bits 2-0 = 0: Horizontal alignment is GENERAL'); - 1: FDetails.Add('Bits 2-0 = 1: Horizontal alignment is LEFT'); - 2: FDetails.Add('Bits 2-0 = 2: Horizontal alignment is CENTERED'); - 3: FDetails.Add('Bits 2-0 = 3: Horizontal alignment is RIGHT'); - 4: FDetails.Add('Bits 2-0 = 4: Horizontal alignment is FILLED'); - end; - if b and $08 = 0 - then FDetails.Add('Bit 3 = 0: Cell has NO left border') - else FDetails.Add('Bit 3 = 1: Cell has left black border'); - if b and $10 = 0 - then FDetails.Add('Bit 4 = 0: Cell has NO right border') - else FDetails.Add('Bit 4 = 1: Cell has right black border'); - if b and $20 = 0 - then FDetails.Add('Bit 5 = 0: Cell has NO top border') - else FDetails.Add('Bit 5 = 1: Cell has top black border'); - if b and $40 = 0 - then FDetails.Add('Bit 6 = 0: Cell has NO bottom border') - else FDetails.Add('Bit 6 = 1: Cell has bottom black border'); - if b and $80 = 0 - then FDetails.Add('Bit 7 = 0: Cell has NO shaded background') - else FDetails.Add('Bit 7 = 1: Cell has shaded background'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.2x)', [b,b]), - 'Cell style'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrROw, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Index of XF record'); - end; - - // Offset 6: Result of formula - numBytes := 8; - Move(FBuffer[FBufferIndex], q, numBytes); - 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 // String result - 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 // BOOL result - 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 // ERROR result - 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 // EMPTY cell - 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; - - // Option flags - if FFormat = sfExcel2 then begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - case b of - 0: FDetails.Add('0 = Do not recalculate'); - 1: FDetails.Add('1 = Recalculate always'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), 'Option flags'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if w and $0001 = 0 - then FDetails.Add('Bit $0001 = 0: Do not recalculate') - else FDetails.Add('Bit $0001 = 1: Recalculate always'); - FDetails.Add('Bit $0002: Reserved - MUST be zero, MUST be ignored'); - if w and $0004 = 0 - then FDetails.Add('Bit $0004 = 0: Cell does NOT have a fill alignment or a center-across-selection alignment.') - else FDetails.Add('Bit $0004 = 1: Cell has either a fill alignment or a center-across-selection alignment.'); - if w and $0008 = 0 - then FDetails.Add('Bit $0008 = 0: Formula is NOT part of a shared formula') - else FDetails.Add('Bit $0008 = 1: Formula is part of a shared formula'); - FDetails.Add('Bit $0010: Reserved - MUST be zero, MUST be ignored'); - if w and $0020 = 0 - then FDetails.Add('Bit $0020 = 0: Formula is NOT excluded from formula error checking') - else FDetails.Add('Bit $0020 = 1: Formula is excluded from formula error checking'); - FDetails.Add('Bits $FC00: Reserved - MUST be zero, MUST be ignored'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), - 'Option flags'); - end; - - // Not used - if (FFormat >= sfExcel5) then begin - numBytes := 4; - ShowInRow(FCurrRow, FBufferIndex, numBytes, '', '(not used'); - end; - - // Size of Token array (in Bytes) - if FFormat = sfExcel2 then begin - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - tokenBytes := b; - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - tokenBytes := WordLEToN(w); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(tokenBytes), - 'Size of formula data (in Bytes)'); - - ShowFormulaTokens(tokenBytes); - - RowCount := FCurrRow; - EndUpdate(true); -end; - - -procedure TBIFFGrid.ShowFormulaTokens(ATokenBytes: Integer); -var - numBytes: Integer; - b: Byte; - w: Word; - s: String; - dbl: Double; - firstTokenBufIndex: Integer; - token: Byte; - r, c: Word; -begin - // Tokens and parameters - firstTokenBufIndex := FBufferIndex; - while FBufferIndex < firstTokenBufIndex + ATokenBytes do begin - token := FBuffer[FBufferIndex]; - numBytes := 1; - case token of - $01: begin - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [token]), - 'Token for "Cell is part of shared formula"'); - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to row of first FORMULA record in the formula range'); - if FFormat = sfExcel2 then begin - numbytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - 'Index to column of first FORMULA record in the formula range'); - end else begin - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to column of first FORMULA record in the formula range'); - end; - end; - $02: begin - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [token]), - 'Token for "Cell is part of a multiple operations table"'); - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first row of the table range'); - if FFormat = sfExcel2 then begin - numbytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - 'Index to first column of the table range'); - end else begin - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first column of the table range'); - end; - end; - $03: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "+" (add)'); - $04: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "-" (subtract)'); - $05: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "*" (multiply)'); - $06: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "/" (divide)'); - $07: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "^" (power)'); - $08: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "&" (concat)'); - $09: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "<" (less than)'); - $0A: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "<=" (less equal)'); - $0B: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "=" (equal)'); - $0C: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token ">=" (greater equal)'); - $0D: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token ">" (greater than)'); - $0E: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "<>" (not equal)'); - $0F: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token " " (intersect)'); - $10: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "list character"'); - $11: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token ":" (range)'); - $12: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "+" (unary plus)'); - $13: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "-" (unary minus)'); - $14: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "%" (percent)'); - $15: ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [token]), - 'Token "()" (operator in parenthesis)'); - $16: ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token "missing argument"'); - $17: begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tSTR (Label)'); - ExtractString(FBufferIndex, 1, (FFormat = sfExcel8), s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'String value'); - end; - $1C: begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tERR (Error)'); - numBytes := 1; - b := FBuffer[FBufferIndex]; - if FCurrRow = Row then begin - FDetails.Add('Error code:'#13); - FDetails.Add(Format('Code $%.2x --> "%s"', [b, GetErrorValueStr(TsErrorValue(b))])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), 'Error code'); - end; - $1D: begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tBOOL'); - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - '0=FALSE, 1=TRUE'); - end; - $1E: begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tINT (Integer)'); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Integer value'); - end; - $1F: begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tNUM (Number)'); - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%g', [dbl]), //FloatToStr(dbl), - 'IEEE 754 floating-point value'); - end; - $20, $40, $60: - begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tARRAY'); - if FFormat = sfExcel2 then numBytes := 6 else numBytes := 7; - ShowInRow(FCurrRow, FBufferIndex, numbytes, '', '(not used)'); - end; - $21, $41, $61: - begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tFUNC (Function with fixed argument count)'); - if FFormat = sfExcel2 then begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - s := Format('Index of function (%s)', [SheetFuncName(b)]); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), s); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - s := Format('Index of function (%s)', [SheetFuncName(w)]); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), s); - end; - end; - $22, $42, $62: - begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tFUNCVAR (Function with variable argument count)'); - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Number of arguments'); - if FFormat = sfExcel2 then begin - numBytes := 1; - s := Format('Index of built-in function (%s)', [SheetFuncName(b)]); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), s); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - s := Format('Index of built-in function (%s)', [SheetFuncName(w)]); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), s); - end; - end; - $23, $43, $63: - begin - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - 'Token tNAME'); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - case FFormat of - sfExcel2: s := 'DEFINEDNAME or EXTERNALNAME record'; - sfExcel5: s := 'DEFINEDNAME record in Global Link Table'; - sfExcel8: s := 'DEFINEDNAME record in Link Table'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - '1-based index to '+s); - case FFormat of - sfExcel2: numBytes := 5; - sfExcel5: numBytes := 12; - sfExcel8: numBytes := 2; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, '', '(not used)'); - end; - $24, $44, $64: - begin - case token of - $24: s := 'reference'; - $44: s := 'value'; - $64: s := 'array'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - Format('Token tREF (Cell %s)', [s])); - ShowCellAddress; - end; - $25, $45, $65: - begin - case token of - $25: s := 'reference'; - $45: s := 'value'; - $65: s := 'array'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - Format('Token tAREA (Cell range %s)', [s])); - ShowCellAddressRange(FFormat); - end; - $2C, $4C, $6C: - begin - case token of - $2C: s := 'reference'; - $4C: s := 'value'; - $6C: s := 'array'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - Format('Token tREFN (Relative reference to cell %s in same sheet)', [s])); - - // Encoded relative cell address - if FFormat = sfExcel8 then - begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); // row - r := WordLEToN(w); - Move(FBuffer[FBufferIndex+2], w, numBytes); // column with flags - c := WordLEToN(w); - - { Note: The bitmask assignment to relative column/row is reversed in relation - to OpenOffice documentation in order to match with Excel files. } - if Row = FCurrRow then begin - FDetails.Add('Encoded cell address (row):'#13); - if c and $8000 = 0 then - begin - FDetails.Add('Row index is ABSOLUTE (see Encoded column index)'); - FDetails.Add('Absolute row index: ' + IntToStr(r)); - end else - begin - FDetails.Add('Row index is RELATIVE (see Encoded column index)'); - FDetails.Add('Relative row index: ' + IntToStr(Smallint(r))); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [r, r]), - 'Encoded row index'); - - // Bit mask $4000 --> column - // Bit mask $8000 --> row - if Row = FCurrRow then - begin - FDetails.Add('Encoded cell address (column):'#13); - if c and $4000 = 0 - then FDetails.Add('Bit 14=0: Column index is ABSOLUTE') - else FDetails.Add('Bit 14=1: Column index is RELATIVE'); - if c and $8000 = 0 - then FDetails.Add('Bit 15=0: Row index is ABSOLUTE') - else FDetails.Add('Bit 15=1: Row index is RELATIVE'); - FDetails.Add(''); - if c and $4000 = 0 - then FDetails.Add('Absolute column index: ' + IntToStr(Lo(c))) - else FDetails.Add('Relative column index: ' + IntToStr(ShortInt(Lo(c)))); - end; - - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [c, c]), - 'Encoded column index'); - end - else - // Excel5 (Excel2 does not support shared formulas) - begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - r := w and $3FFF; - b := FBuffer[FBufferIndex+2]; - c := b; - - // Bit mask $4000 --> column - // Bit mask $8000 --> row - if Row = FCurrRow then begin - FDetails.Add('Encoded cell address (row):'#13); - if w and $4000 = 0 - then FDetails.Add('Bit 14=0: Column index is ABSOLUTE') - else FDetails.Add('Bit 14=0: Column index is RELATIVE'); - if w and $8000 = 0 - then FDetails.Add('Bit 15=0: Row index is ABSOLUTE') - else FDetails.Add('Bit 15=1: Row index is RELATIVE'); - FDetails.Add(''); - if w and $8000 = 0 - then FDetails.Add('Absolute row index: ' + IntToStr(r)) - else FDetails.Add('Relative row index: ' + IntToStr(Smallint(r))); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Encoded row index'); - - if Row = FCurrRow then - begin - FDetails.Add('Encoded cell address (column):'#13); - if w and $4000 = 0 then begin - FDetails.Add('Column index is ABSOLUTE (see Encoded row index)'); - FDetails.Add('Absolute column index: ' + IntToStr(c)); - end else begin - FDetails.Add('Column index is RELATIVE (see Encoded row index)'); - FDetails.Add('Relative column index: ' + IntToStr(ShortInt(c))); - end; - end; - numBytes := 1; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b, b]), - 'Encoded column index'); - end; - end; - - else - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]), - '(unknown token)'); - - end; // case - end; // while - -end; - -procedure TBIFFGrid.ShowGCW; -var - numBytes: Integer; - b: Byte; - w: Word; - i,j: Integer; - bit: Byte; -begin - RowCount := FixedRows + 33; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Size of Global Column Width bit field (1 bit per column), must be 32'); - - numBytes := 1; - for i:= 0 to w-1 do begin - b := FBuffer[FBufferIndex]; - if FCurrRow = Row then begin - FDetails.Add(Format('GCW (Global column width) record, byte #%d:'#13, [i])); - bit := 1; - for j:=0 to 7 do begin - if b and bit = 0 - then FDetails.Add(Format('Bit $%.2x=0: Column %d uses width of COLWIDTH record.', [bit, j+i*8])) - else FDetails.Add(Format('Bit $%.2x=1: Column %d uses width of STANDARDWIDTH record '+ - '(or, if not available, DEFCOLWIDTH record)', [bit, j+i*8])); - bit := bit * 2; - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), - Format('Widths of columns %d-%d', [i*8, i*8+7])); - end; -end; - - -procedure TBIFFGrid.ShowHeader; -var - numbytes: Integer; - s: String; -begin - RowCount := FixedRows + 1; - if Length(FBuffer) = 0 then - ShowInRow(FCurrRow, FBufferIndex, 0, '', '(empty record)') - else - begin - ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8, - 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; - - -procedure TBIFFGrid.ShowHideObj; -var - numBytes: word; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Viewing mode for objects:'#13); - case w of - 0: FDetails.Add('0 = Show all objects'); - 1: FDetails.Add('1 = Show placeholders'); - 2: FDetails.Add('2 = Do not show objects'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Viewing mode for objects'); -end; - - -procedure TBIFFGrid.ShowHyperlink; -var - numbytes: Word; - w: Word; - dw: DWord; - n: Integer; - guid: TGUID; - flags: DWord; - nchar, size: DWord; - widestr: WideString; - ansistr: ansistring; - s: String; -begin - n := 0; - RowCount := FixedRows + 1000; - - ShowCellAddressRange(FFormat); - inc(n, 4); - - numbytes := 16; - Move(FBuffer[FBufferIndex], guid, numbytes); - s := GuidToString(guid); - ShowInRow(FCurrRow, FBufferIndex, numbytes, GuidToString(guid), 'GUID of standard link'); - inc(n); - - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordToLE(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x (%d)', [dw, dw]), 'Unknown'); - inc(n); - - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - flags := DWordToLE(dw); - if FCurrRow = row then begin - FDetails.Add('Option flags:'#13); - if flags and $0001 = 0 - then FDetails.Add(' Bit $0001=0: No link') - else FDetails.ADd('* Bit $0001=1: File link or URL'); - if flags and $0002 = 0 - then FDetails.Add(' Bit $0002=0: Relative path') - else FDetails.Add('* Bit $0002=1: Absolute path'); - if flags and $0014 = 0 - then FDetails.Add(' Bits $0014=0: No desriptions') - else FDetails.Add('* Bits $0014=1: Description (both bits)'); - if flags and $0008 = 0 - then FDetails.Add(' Bit $0008=0: No text mark') - else FDetails.Add('* Bit $0008=1: Text mark'); - if flags and $0080 = 0 - then FDetails.Add(' Bit $0080=0: No target frame') - else FDetails.Add('* Bit $0080=1: Target frame'); - if flags and $0100 = 0 - then FDetails.Add(' Bit $0100=0: File link or URL') - else FDetails.Add('* Bit $0100=1: UNC path (incl server name)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x (%d)', [flags, flags]), - 'Option flags'); - inc(n); - - if flags and $0014 = $0014 then // hyperlink has description - begin - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - nchar := DWordToLE(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(nchar), - 'Character count of description text, incl trailing zero word'); - inc(n); - - numbytes := 2*nchar; - SetLength(widestr, nchar); - Move(FBuffer[FBufferIndex], widestr[1], 2*nchar); - s := UTF16ToUTF8(widestr); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Character array of description text (no unicode string header, always 16-bit characters, zero-terminated)'); - inc(n); - end; - - if flags and $0080 <> 0 then // Hyperlink has target frame - begin - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - nchar := DWordToLE(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(nchar), - 'Character count of target frame, incl trailing zero word'); - inc(n); - - numbytes := 2*nchar; - SetLength(widestr, nchar); - Move(FBuffer[FBufferIndex], widestr[1], 2*nchar); - s := UTF16ToUTF8(widestr); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Character array of target frame (no unicode string header, always 16-bit characters, zero-terminated)'); - inc(n); - end; - - if flags and $0011 <> 0 then // hyperlink contains URL ***OR*** a local file - begin - numbytes := 16; - Move(FBuffer[FBufferIndex], guid, numbytes); - s := GuidToString(guid); - if s = '{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}' then // case: URL - begin - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'GUID of URL Moniker'); - inc(n); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - size := DWordToLE(dw); - nchar := size div 2 - 1; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(size), - 'Size of URL character array, incl. trailing zero word'); - inc(n); - - numbytes := 2*nchar; - SetLength(widestr, nchar); - Move(FBuffer[FBufferIndex], widestr[1], 2*nchar); - s := UTF16ToUTF8(widestr); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Character array of the URL (no unicode string header, always 16-bit characters, zero-terminated'); - inc(n); - end else - if s = '{00000303-0000-0000-C000-000000000046}' then // case: local file - begin - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'GUID of File Moniker'); - inc(n); - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Directory up-level count. Each leading "..\" in the file link is deleted and increases this counter.'); - inc(n); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - nchar := DWordToLE(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(nchar), - 'Character count of the shortened file path and name, incl trailing zero byte.'); - inc(n); - - numbytes := nchar; - SetLength(ansistr, nchar); - Move(FBuffer[FBufferIndex], ansistr[1], nchar); - s := AnsiToUTF8(ansistr); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Character array of the shortened file path and name (no unicode string header, always 8-bit characters, zero-terminated)'); - inc(n); - - for w := 1 to 6 do begin - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [DWordToLE(dw)]), - 'Unknown'); - inc(n); - end; - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - size := DWordToLE(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(size), - 'Size of following file link field incl string length field and additional data field'); - inc(n); - - if size > 0 then begin - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - size := DWordToLE(dw); - nchar := size div 2; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(size), - 'Size of extended file path and name character array'); - inc(n); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordToLE(w)), - 'Unknown'); - inc(n); - - numBytes := size; - SetLength(widestr, nchar); - Move(FBuffer[FBufferIndex], widestr[1], numbytes); - s := UTF16ToUTF8(widestr); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Character array of extended file path and array (No unicode string header, always 16-bit characters, NOT zero-terminated)'); - inc(n); - end; - end; - end // if flags and $0011 <> 0 - else begin - // case: Hyperlink to current workbook - end; - - if flags and $0008 <> 0 then // hyperlink contains text mark field - begin - numBytes := 4; - - Move(FBuffer[FBufferIndex], dw, numbytes); - nchar := DWordToLE(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(nchar), - 'Character count of the text mark, incl trailing zero word'); - inc(n); - - numbytes := 2*nchar; - SetLength(widestr, nchar); - Move(FBuffer[FBufferIndex], widestr[1], 2*nchar); - s := UTF16ToUTF8(widestr); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Character array of the text mark, without "#" sign, no unicode string header, always 16-bit characters, zero-terminated)'); - inc(n); - end; - - RowCount := FixedRows + n; -end; - - -procedure TBIFFGrid.ShowHyperlinkTooltip; -var - numbytes: Word; - w: Word; - widestr: widestring; - s: string; -begin - RowCount := FixedRows + 6; - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordToLE(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x (%d)', [w, w]), - 'Repeated record ID'); - - ShowCellAddressRange(sfExcel8); - - numbytes := Length(FBuffer) - FBufferIndex; - SetLength(widestr, numbytes div 2); - Move(FBuffer[FBufferIndex], widestr[1], numbytes); - s := UTF16toUTF8(widestr); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - 'Character array of the tool tip, no Unicode string header, always 16-bit characters, zero-terminated'); -end; - - -procedure TBIFFGrid.ShowInRow(var ARow: Integer; var AOffs: LongWord; - ASize: Word; AValue,ADescr: String; ADescrOnly: Boolean = false); -begin - if ADescrOnly then - begin - Cells[0, ARow] := ''; - Cells[1, ARow] := ''; - Cells[2, ARow] := ''; - end else - begin - Cells[0, ARow] := IntToStr(AOffs); - Cells[1, ARow] := IntToStr(ASize); - Cells[2, ARow] := AValue; - end; - Cells[3, ARow] := ADescr; - inc(ARow); - inc(AOffs, ASize); -end; - - -procedure TBIFFGrid.ShowInteger; -var - numBytes: Integer; - w: Word; - b: Byte; -begin - // BIFF2 only - if (FFormat <> sfExcel2) then - exit; - - RowCount := FixedRows + 5; - ShowRowColData(FBufferIndex); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Cell protection and XF index:'#13); - FDetails.Add(Format('x Bits 5-0 = %d: XF Index', [b and $3F])); - case b and $40 of - 0: FDetails.Add(' Bit 6 = 0: Cell is NOT locked.'); - 1: FDetails.Add('x Bit 6 = 1: Cell is locked.'); - end; - case b and $80 of - 0: FDetails.Add(' Bit 7 = 0: Formula is NOT hidden.'); - 1: FDetails.Add('x Bit 7 = 1: Formula is hidden.'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Cell protection and XF index'); - - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Indexes to format and font records:'#13); - FDetails.Add(Format('Bits 5-0 = %d: Index to FORMAT record', [b and $3f])); - FDetails.Add(Format('Bits 7-6 = %d: Index to FONT record', [(b and $C0) shr 6])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Indexes of format and font records'); - - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Cell style:'#13); - case b and $07 of - 0: FDetails.Add('x Bits 2-0 = 0: Horizontal alignment is GENERAL'); - 1: FDetails.Add('x Bits 2-0 = 1: Horizontal alignment is LEFT'); - 2: FDetails.Add('x Bits 2-0 = 2: Horizontal alignment is CENTERED'); - 3: FDetails.Add('x Bits 2-0 = 3: Horizontal alignment is RIGHT'); - 4: FDetails.Add('x Bits 2-0 = 4: Horizontal alignment is FILLED'); - end; - if b and $08 = 0 - then FDetails.Add(' Bit 3 = 0: Cell has NO left border') - else FDetails.Add('x Bit 3 = 1: Cell has left black border'); - if b and $10 = 0 - then FDetails.Add(' Bit 4 = 0: Cell has NO right border') - else FDetails.Add('x Bit 4 = 1: Cell has right black border'); - if b and $20 = 0 - then FDetails.Add(' Bit 5 = 0: Cell has NO top border') - else FDetails.Add('x Bit 5 = 1: Cell has top black border'); - if b and $40 = 0 - then FDetails.Add(' Bit 6 = 0: Cell has NO bottom border') - else FDetails.Add('x Bit 6 = 1: Cell has bottom black border'); - if b and $80 = 0 - then FDetails.Add(' Bit 7 = 0: Cell has NO shaded background') - else FDetails.Add('x Bit 7 = 1: Cell has shaded background'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.2x)', [b,b]), - 'Cell style'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Unsigned 16-bit integer cell value'); -end; - - -procedure TBIFFGrid.ShowInterfaceEnd; -begin - RowCount := FixedRows + 1; - ShowInRow(FCurrRow, FBufferIndex, 0, '', 'End of Globals Substream'); -end; - - -procedure TBIFFGrid.ShowInterfaceHdr; -var - numbytes: Integer; - w: Word; -begin - if FFormat < sfExcel8 then begin - RowCount := FixedRows; - exit; - end; - - RowCount := FixedRows + 1; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Code page of user interface:'#13); - FDetails.Add(Format('$%.4x = %s', [w, CodePageName(w)])); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w, w]), - 'Begin of Globals Substream, code page of user interface'); -end; - - -procedure TBIFFGrid.ShowIteration; -var - numBytes: Integer; - w: word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Iterations:'#13); - case w of - 0: FDetails.Add('0 = Iterations off'); - 1: FDetails.Add('1 = Iterations on'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Iterations on/off'); -end; - - -procedure TBIFFGrid.ShowIXFE; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to XF record'); -end; - -// Called for LABEL -procedure TBIFFGrid.ShowLabelCell; -var - numBytes: Integer; - b: Byte; - w: Word; - s: String; -begin - RowCount := IfThen(FFormat = sfExcel2, FixedRows + 6, FixedRows + 4); - ShowRowColData(FBufferIndex); - if (FFormat = sfExcel2) then begin - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell protection and XF index:'#13); - FDetails.Add(Format('x Bits 5-0 = %d: XF Index', [b and $3F])); - case b and $40 of - 0: FDetails.Add(' Bit 6 = 0: Cell is NOT locked.'); - 1: FDetails.Add('x Bit 6 = 1: Cell is locked.'); - end; - case b and $80 of - 0: FDetails.Add(' Bit 7 = 0: Formula is NOT hidden.'); - 1: FDetails.Add('x Bit 7 = 1: Formula is hidden.'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Cell protection and XF index'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Indexes to format and font records:'#13); - FDetails.Add(Format('Bits 5-0 = %d: Index to FORMAT record', [b and $3f])); - FDetails.Add(Format('Bits 7-6 = %d: Index to FONT record', [(b and $C0) shr 6])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Indexes of format and font records'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell style:'#13); - case b and $07 of - 0: FDetails.Add('Bits 2-0 = 0: Horizontal alignment is GENERAL'); - 1: FDetails.Add('Bits 2-0 = 1: Horizontal alignment is LEFT'); - 2: FDetails.Add('Bits 2-0 = 2: Horizontal alignment is CENTERED'); - 3: FDetails.Add('Bits 2-0 = 3: Horizontal alignment is RIGHT'); - 4: FDetails.Add('Bits 2-0 = 4: Horizontal alignment is FILLED'); - end; - if b and $08 = 0 - then FDetails.Add('Bit 3 = 0: Cell has NO left border') - else FDetails.Add('Bit 3 = 1: Cell has left black border'); - if b and $10 = 0 - then FDetails.Add('Bit 4 = 0: Cell has NO right border') - else FDetails.Add('Bit 4 = 1: Cell has right black border'); - if b and $20 = 0 - then FDetails.Add('Bit 5 = 0: Cell has NO top border') - else FDetails.Add('Bit 5 = 1: Cell has top black border'); - if b and $40 = 0 - then FDetails.Add('Bit 6 = 0: Cell has NO bottom border') - else FDetails.Add('Bit 6 = 1: Cell has bottom black border'); - if b and $80 = 0 - then FDetails.Add('Bit 7 = 0: Cell has NO shaded background') - else FDetails.Add('Bit 7 = 1: Cell has shaded background'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.2x)', [b,b]), - 'Cell style'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Index of XF record'); - end; - - b := IfThen(FFormat=sfExcel2, 1, 2); - ExtractString(FBufferIndex, b, (FFormat = sfExcel8), s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, - Format('%s string, %d-bit string length', [GetStringType, b*8])); -end; - - -procedure TBIFFGrid.ShowLabelSSTCell; -var - numBytes: Integer; - w: Word; - dw: DWord; -begin - RowCount := FixedRows + 4; - ShowRowColData(FBufferIndex); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Index of XF record'); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(dw), - 'Index into SST record (shared string table)'); -end; - - -procedure TBIFFGrid.ShowLeftMargin; -var - numBytes: Integer; - dbl: Double; -begin - RowCount := FixedRows + 1; - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl), - 'Left page margin in inches (IEEE 754 floating-point value, 64-bit double precision)'); -end; - - -procedure TBIFFGrid.ShowMergedCells; -var - w: Word; - numBytes: Integer; - i, n: Integer; -begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - n := WordLEToN(w); // count of merged ranges in this record - - RowCount := FixedRows + 1 + n*4; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(n), - 'Count of merged ranges in this record'); - - for i:=1 to n do begin - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - Format('Merged range #%d: First row = %d', [i, w])); - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - Format('Merged range #%d: Last row = %d', [i, w])); - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - Format('Merged range #%d: First column = %d', [i, w])); - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - Format('Merged range #%d: Last column = %d', [i, w])); - end; -end; - - -procedure TBIFFGrid.ShowMMS; -var - w: Word; - numbytes: Integer; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), 'Reserved, MUST be ignored'); -end; - -{ Only those records needed for comments are deciphered. } -procedure TBIFFGrid.ShowMSODrawing; -var - n: Integer; - numBytes: Integer; - w: Word; - dw: DWord; - recType: Word; - recLen: DWord; - isContainer: Boolean; - indent: String; - level: Integer; - - function PrepareIndent(ALevel: Integer): String; - var - i: Integer; - begin - Result := ''; - for i := 1 to ALevel do Result := Result + ' '; - end; - - procedure DoShowHeader(out ARecType: Word; out ARecLen: DWord; - out IsContainer: Boolean); - var - s: String; - instance: Word; - version: Word; - begin - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - IsContainer := (w and $000F = $000F); - - if IsContainer and (FBufferIndex > 0) then - indent := PrepareIndent(level+1); - - s := IfThen(IsContainer, '***** CONTAINER *****', '--- ATOM ---'); - ShowInRow(FCurrRow, FBufferIndex, 0, '', indent + s, TRUE); - inc(n); - - version := w and $000F; - instance := (w and $FFF0) shr 4; - if Row = FCurrRow then begin - FDetails.Add('OfficeArtDrawing Header:'#13); - FDetails.Add(Format('Bits 3-0 = $%.1x: Version', [version])); - FDetails.Add(Format('Bits 15-4 = $%.3x: Instance', [instance])); - end; - s := Format('OfficeArtDrawing Header: Version %d, instance %d', [version, instance]); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.04x', [w]), indent + s); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ARecType := w; - case ARecType of - $F00A: //, $F00B: - case instance of - $01: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Rectangle)'; - $02: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Rounded rectangle)'; - $03: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Ellipse)'; - $04: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Diamond)'; - $05: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Triangle)'; - $06: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Right triangle)'; - $07: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Parallelogram)'; - $08: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Trapezoid)'; - $09: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Hexagon)'; - $0A: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Pentagon)'; - $0B: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Plus)'; - $0C: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Star)'; - $0D: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Arrow)'; - $0E: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Thick arrow)'; - $0F: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Irregular pentagon)'; - $10: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Cube)'; - $11: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Speech balloon)'; - $12: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Seal)'; - $13: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Curved arc)'; - $14: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Line)'; - $15: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Plaque)'; - $16: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Cylinder)'; - $17: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Donut)'; - $CA: Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + ' (Text box)'; - end; - $F00B: - Cells[3, FCurrRow-1] := Cells[3, FCurrRow-1] + Format(' (i.e., %d properties)', [instance]); - end; - - case ARecType of - $F000: s := 'OfficeArtDggContainer (all the OfficeArt file records containing document-wide data)'; - $F001: s := 'OfficeArtBStoreContainer (all the BLIPs used in all the drawings associated with parent OfficeArtDggContainer record)'; - $F002: s := 'OfficeArtDgContainer (all file records for the objects in a drawing)'; - $F003: s := 'OfficeArtSpgrContainer (groups of shapes)'; - $F004: s := 'OfficeArtSpContainer (shape)'; - $F005: s := 'OfficeArtSolverContainer (rules applicable to the shapes contained in an OfficeArtDgContainer record)'; - $F006: s := 'OfficeArtFDGGBlock record (document-wide information about all drawings saved in the file)'; - $F007: s := 'OfficeArtFBSE record (File BLIP Store Entry (FBSE) containing information about the BLIP)'; - $F008: s := 'OfficeArtFDG record (number of shapes, drawing identifier, and shape identifier of the last shape in a drawing)'; - $F009: s := 'OfficeArtFSPGR record (coordinate system of the group shape that the anchors of the child shape are expressed in)'; - $F00A: s := 'OfficeArtFSP record (instance of a shape)'; - $F00B: s := 'OfficeArtFOPT record (table of OfficeArtRGFOPTE records)'; - $F00D: s := 'OfficeArtClientTextBox (text related data for a shape)'; - $F00F: s := 'OfficeArtChildAnchor record (anchors for the shape containing this record)'; - $F010: s := 'OfficeArtClientAnchor record (location of a shape)'; - $F011: s := 'OfficeArtClientData record (information about a shape)'; - $F012: s := 'OfficeArtFConnectorRule record (connection between two shapes by a connector shape)'; - $F014: s := 'OfficeArtFArcRule record (Specifies an arc rule. Each arc shape MUST correspond to a unique arc rule)'; - $F017: s := 'OfficeArtFCalloutRule record (Callout rule: One callout rule MUST exist per callout shape)'; - $F01A: s := 'OfficeArtBlipEMF record (BLIP file data for the enhanced metafile format (EMF))'; - $F01B: s := 'OfficeArtBlipWMF record (BLIP file data for the Windows Metafile Format (WMF))'; - $F01C: s := 'OfficeArtBlipPICT record (BLIP file data for the Macintosh PICT format)'; - $F01D: s := 'OfficeArtBlipJPEG record (BLIP file data for the Joint Photographic Experts Group (JPEG) format)'; - $F01E: s := 'OfficeArtBlipPNG record (BLIP file data for the Portable Network Graphics (PNG) format)'; - $F01F: s := 'OfficeArtBlipDIB record (BLIP file data for the device-independent bitmap (DIB) format)'; - $F029: s := 'OfficeArtBlipTIFF record (BLIP file data for the TIFF format)'; - $F118: s := 'OfficeArtFRITContainer record (container for the table of group identifiers that are used for regrouping ungrouped shapes)'; - $F119: s := 'OfficeArtFDGSL record (specifies both the selected shapes and the shape that is in focus in the drawing)'; - $F11A: s := 'OfficeArtColorMRUContainer record (most recently used custom colors)'; - $F11D: s := 'OfficeArtFPSPL record (former hierarchical position of the containing object that is either a shape or a group of shapes)'; - $F11E: s := 'OfficeArtSplitMenuColorContainer record (container for the colors that were most recently used to format shapes)'; - $F121: s := 'OfficeArtSecondaryFOPT record (table of OfficeArtRGFOPTE records)'; - $F122: s := 'OfficeArtTertiaryFOPT record (table of OfficeArtRGFOPTE records)'; - else s := 'Not known to BIFFExplorer'; - end; - if Row = FCurrRow then begin - FDetails.Add('OfficeArtDrawing Record Type:'#13); - FDetails.Add(Format('$%.4x: %s', [ARecType, s])); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), - indent + 'Record type: ' + s); - inc(n); - - numbytes := 4; - Move(FBuffer[FbufferIndex], ARecLen, Numbytes); - ARecLen := DWordLEToN(ARecLen); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d', [ARecLen]), - indent + 'Record length'); - inc(n); - end; - - procedure DoShowOfficeArtFDG; // $F008 - // The OfficeArtFDG record specifies the number of shapes, the drawing - // identifier, and the shape identifier of the last shape in a drawing. - begin - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(dw), - indent + 'Number of shapes in this drawing'); - inc(n); - - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(dw), - indent + 'Shape identifier of the last shape in this drawing'); - inc(n); - end; - - procedure DoShowOfficeArtFSPGR; // $F009 - // The OfficeArtFSPGR record specifies the coordinate system of the group - // shape that the anchors of the child shape are expressed in. This record - // is present only for group shapes. - var - rt: Word; - begin - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(LongInt(DWordLEToN(dw))), - indent + 'xLeft'); - inc(n); - - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(LongInt(DWordLEToN(dw))), - indent + 'yTop'); - inc(n); - - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(LongInt(DWordLEToN(dw))), - indent + 'xRight'); - inc(n); - - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(LongInt(DWordLEToN(dw))), - indent + 'yBottom'); - inc(n); - end; - - procedure DoShowOfficeArtFSP; // §F00A - // The OfficeArtFSP record specifies an instance of a shape. - // The record header contains the shape type, and the record itself - // contains the shape identifier and a set of bits that further define the shape. - var - rt: word; - s: String; - begin - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), - indent + 'Shape identifier'); - inc(n); - - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - s := ''; - if Row = FCurrRow then begin - FDetails.Add('Shape options:'#13); - if dw and $0001 = 0 - then FDetails.Add(' Bit 1=0: Shape is NOT a group shape') - else FDetails.Add('x Bit 1=1: Shape is a group shape'); - if dw and $0002 = 0 - then FDetails.Add(' Bit 2=0: Shape is NOT a child shape') - else FDetails.Add('x Bit 2=1: Shape is a child shape'); - if dw and $0004 = 0 - then FDetails.Add(' Bit 3=0: Shape is NOT the top-most group shape (patriarch)') - else FDetails.Add('x Bit 3=1: Shaoe is the top-most group shape (patriarch)'); - if dw and $0008 = 0 - then FDetails.Add(' Bit 4=0: Shape has NOT been deleted') - else FDetails.Add('x Bit 4=1: Shape has been deleted'); - if dw and $0010 = 0 - then FDetails.Add(' Bit 5=0: Shape is NOT an OLE object') - else FDetails.Add('x Bit 5=1: Shape is an OLE object'); - if dw and $0020 = 0 - then FDetails.Add(' Bit 6=0: Shape does NOT have a valid master in the hspMaster property') - else FDetails.Add('x Bit 6=1: Shape has a valid master in the hspMaster property'); - if dw and $0040 = 0 - then FDetails.Add(' Bit 7=0: Shape is NOT horizontally flipped') - else FDetails.Add('x Bit 7=1: Shape is horizontally flipped'); - if dw and $0080 = 0 - then FDetails.Add(' Bit 8=0: Shape is NOT vertically flipped') - else FDetails.Add('x Bit 8=1: Shape is vertically flipped'); - if dw and $0100 = 0 - then FDetails.Add(' Bit 9=0: Shape is NOT a connector shape') - else FDetails.Add('x Bit 9=1: Shape is a connector shape'); - if dw and $0200 = 0 - then FDetails.Add(' Bit 10=0: Shape doe NOT have an anchor') - else FDetails.Add('x Bit 10=1: Shape has an anchor'); - if dw and $0400 = 0 - then FDetails.Add(' Bit 11=0: Shape is NOT a background shape') - else FDetails.Add('x Bit 11=1: Shape is a background shape'); - if dw and $0800 = 0 - then FDetails.Add(' Bit 12=0: Shape does NOT have a shape type property') - else FDetails.Add('x Bit 12=1: Shape has a shape type property'); - FDetails.Add(' Bits 13-32: unused'); - end; - s := ''; - if dw and $0001 <> 0 then s := s + 'group shape, '; - if dw and $0002 <> 0 then s := s + 'child shape, '; - if dw and $0004 <> 0 then s := s + 'patriarch, '; - if dw and $0008 <> 0 then s := s + 'deleted, '; - if dw and $0010 <> 0 then s := s + 'OLE object, '; - if dw and $0020 <> 0 then s := s + 'master, '; - if dw and $0040 <> 0 then s := s + 'flipped hor, '; - if dw and $0080 <> 0 then s := s + 'flipped vert, '; - if dw and $0100 <> 0 then s := s + 'connector shape, '; - if dw and $0200 <> 0 then s := s + 'anchor, '; - if dw and $0400 <> 0 then s := s + 'background, '; - if dw and $0800 <> 0 then s := s + 'shape type, '; - if s <> '' then begin - Delete(s, Length(s)-1, 2); - s := 'Shape options: ' + s; - end else - s := 'Shape options'; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x (%d)', [dw, dw]), indent + s); - inc(n); - end; - - procedure DoShowOfficeArtFOPT(ARecLen: DWord); // $F00B - // The OfficeArtFOPT record specifies a table of OfficeArtRGFOPTE records. - var - startIndex: Int64; - opid: Word; - op: DWord; - s: String; - begin - startIndex := FBufferIndex; - while FBufferIndex < startIndex + ARecLen do - begin - numbytes := 2; - Move(FBuffer[FBufferIndex], opid, numbytes); - opid := WordLEToN(opid); - case opid of - $007F: s := 'OfficeArtFOPTEOPID: Protection boolean properties'; - $0080: s := 'OfficeArtFOPTEOPID: TextID'; - $0081: s := 'OfficeArtFOPTEOPID: dxTextLeft'; - $0082: s := 'OfficeArtFOPTEOPID: dyTextTop'; - $0083: s := 'OfficeArtFOPTEOPID: dxTextRight'; - $0084: s := 'OfficeArtFOPTEOPID: dyTextBottom'; - $0085: s := 'OfficeArtFOPTEOPID: Wrap text'; - $0086: s := 'OfficeArtFOPTEOPID: Unused'; - $0087: s := 'OfficeArtFOPTEOPID: Text anchor'; - $0088: s := 'OfficeArtFOPTEOPID: Text flow'; - $0089: s := 'OfficeArtFOPTEOPID: Font rotation'; - $008A: s := 'OfficeArtFOPTEOPID: Next shape in sequence of linked shapes'; - $008B: s := 'OfficeArtFOPTEOPID: Text direction'; - $008C: s := 'OfficeArtFOPTEOPID: Unused'; - $008D: s := 'OfficeArtFOPTEOPID: Unused'; - $00BF: s := 'OfficeArtFOPTEOPID: Boolean properties for the text in a shape'; - $00C0: s := 'OfficeArtFOPTEOPID: Text for this shape’s geometry text'; - $00C2: s := 'OfficeArtFOPTEOPID: Alignment of text in the shape'; - $00C3: s := 'OfficeArtFOPTEOPID: Font size, in points, of the geometry text for this shape'; - $00C4: s := 'OfficeArtFOPTEOPID: Amount of spacing between characters in the text'; - $00C5: s := 'OfficeArtFOPTEOPID: Font to use for the text'; - $0158: s := 'OfficeArtFOPTEOPID: Type of connection point'; - $0181: s := 'OfficeArtFOPTEOPID: Fill color'; - $0183: s := 'OfficeArtFOPTEOPID: Background color of the fill'; - $0185: s := 'OfficeArtFOPTEOPID: Foreground color of the fill'; - $01BF: s := 'OfficeArtFOPTEOPID: Fill style boolean properties'; - $01C0: s := 'OfficeArtFOPTEOPID: Line color'; - $01C3: s := 'OfficeArtFOPTEOPID: Line foreground color for black & white display mode'; - $01FF: s := 'OfficeArtFOPTEOPID: Line style boolean properties'; - $0201: s := 'OfficeArtFOPTEOPID: Shadow color'; - $0203: s := 'OfficeArtFOPTEOPID: Shadow primary color modifier if in black & white mode'; - $023F: s := 'OfficeArtFOPTEOPID: Shadow style boolean properties'; - $03BF: s := 'OfficeArtFOPTEOPID: Group shape boolean properties'; - else s := 'OfficeArtFOPTEOPID that specifies the header information for this property'; - end; - s := indent + s; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x (%d)', [opid, opid]), s); - inc(n); - - numbytes := 4; - Move(FBuffer[FBufferIndex], op, numbytes); - op := DWordLEToN(op); - s := ''; - case opid of - $0087: case op of - 0: s := s + ': text at top'; - 1: s := s + ': text vertically centered'; - 2: s := s + ': text at bottom'; - 3: s := s + ': text at top and centered horizontally'; - 4: s := s + ': text at center of box'; - 5: s := s + ': text at bottom and centered horizontally'; - end; - $0089: case op of - 0: s := s + ': horizontal'; - 1: s := s + ': 90° clockwise, vertical down'; - 2: s := s + ': horizontal, 180° rotated'; - 3: s := s + ': 90° counter-clickwise, vertical up'; - end; - $008B: case op of - 0: s := s + ': left-to-right'; - 1: s := s + ': right-to-left'; - 2: s := s + ': determined from text string'; - end; - $00C2: case op of - 0: s := s + ': stretched'; - 1: s := s + ': centered'; - 2: s := s + ': left-aligned'; - 3: s := s + ': right-aligned'; - 4: s := s + ': justified'; - 5: s := s + ': word-justified'; - end; - $0158: case op of - 0: s := s + ': no connection point'; - 1: s := s + ': Edit points of shape are used as connection points'; - 2: s := s + ': Custom array of connection points'; - 3: s := s + ': standard 4 connection points at the top, bottom, left, and right side centers'; - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x (%d)', [op, op]), - indent + 'Value of this property' + s); - inc(n); - end; - end; - - procedure DoShowOfficeArtClientTextbox(ARecLen: Word); // $F00D - begin - numBytes := ARecLen; - ShowInRow(FCurrRow, FBufferIndex, numbytes, '...', indent + 'Text data follow in TXO record', true); - inc(n); - end; - - procedure DoShowOfficeArtClientAnchorData(StructureKind: Integer); // $F010 - begin - case StructureKind of - 0: begin // OfficeArtClientAnchorSheet - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Move/resize flags:'#13); - if w and $0001 = 0 - then FDetails.Add(' Bit 0=0: Shape will NOT be kept intact when the cells are moved') - else FDetails.Add('x Bit 0=1: Shape will be kept intact when the cells are moved'); - if w and $0002 = 0 - then FDetails.Add(' Bit 1=0: Shape will NOT be kept intact when the cells are resized') - else FDetails.Add('x Bit 1=1: Shape will be kept intact when the cells are resized'); - FDetails.Add( ' Bit 2=0: reserved (must be 0)'); - FDetails.Add( ' Bit 3=0: reserved (must be 0)'); - FDetails.Add( ' Bit 4=0: reserved (must be 0)'); - FDetails.Add( ' Bits 15-5: unused'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), indent + 'Move/resize flags'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'Column of the cell under the top left corner of the bounding rectangle of the shape'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'x coordinate of the top left corner of the bounding rectangle relative to the corner of the underlying cell (as 1/1024 of that cell’s width)'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'Row of the cell under the top left corner of the bounding rectangle of the shape'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'y coordinate of the top left corner of the bounding rectangle relative to the corner of the underlying cell (as 1/256 of that cell’s height'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'Column of the cell under the bottom right corner of the bounding rectangle of the shape'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'x coordinate of the bottom right corner of the bounding rectangle relative to the corner of the underlying cell (as 1/1024 of that cell’s width)'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'Row of the cell under the bottom right corner of the bounding rectangle of the shape'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'y coordinate of the bottom right corner of the bounding rectangle relative to the corner of the underlying cell (as 1/256 of that cell’s height'); - inc(n); - end; - 1: begin // "Small" rectangle structure - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'top'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'left'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'right'); - inc(n); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - indent + 'bottom'); - inc(n); - end; - 2: begin // standard rectangle structure - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), - indent + 'top'); - inc(n); - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), - indent + 'left'); - inc(n); - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), - indent + 'right'); - inc(n); - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), - indent + 'bottom'); - inc(n); - end; - end; - end; - - procedure DoShowOfficeArtRecord(out ARecType:Word; out ARecLen: DWord; - out AIsContainer: Boolean); - var - startIndex, endindex: Int64; - totalbytes: Int64; - begin - totalbytes := 0; - startIndex := FBufferIndex + 8; - repeat - DoShowHeader(ARecType, ARecLen, AIsContainer); - if totalbytes = 0 then endindex := startindex + ARecLen; - totalbytes := totalbytes + ARecLen; - if AIsContainer then begin - inc(level); - indent := PrepareIndent(level); - DoShowOfficeArtRecord(ARecType, ARecLen, AIsContainer); - end else - case ARecType of - $F008: DoShowOfficeArtFDG; - $F009: DoShowOfficeArtFSPGR; // shape group - $F00A: DoShowOfficeArtFSP; // instance of a shape - $F00B: DoShowOfficeArtFOPT(ARecLen); // table of OfficeArtRGFOPTE records - $F00D: DoShowOfficeArtClientTextbox(ARecLen); - $F010: DoShowOfficeArtClientAnchorData(0); // 0 - use OfficeArtClientAnchorSheet because contained in a sheet stream -// $F122: DoShowOfficeArtRGFOPTE(AIndent); // (tertiary) table of OfficeArtRGFOPTE records - else if ARecLen <> 0 then begin - ShowInRow(FCurrRow, FBufferIndex, ARecLen, '', indent + 'Skipping this unknown record...'); - inc(n); - end; - end; - until (FBufferIndex >= endindex) or (FBufferIndex >= Length(FBuffer)); - dec(level); - FBufferIndex := endindex; - end; - -begin - RowCount := FixedRows + 1000; - n := 0; - level := -1; - DoShowOfficeArtRecord(recType, recLen, isContainer); - RowCount := FixedRows + n; -end; - -procedure TBIFFGrid.ShowMulBlank; -var - w: Word; - numbytes: Integer; - i, nc: Integer; -begin - nc := (Length(FBuffer) - 6) div 2; - RowCount := FixedRows + 3 + nc; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to row'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first column'); - - for i:=0 to nc-1 do begin - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - Format('Index to XF record #%d', [i])); - end; - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to last column'); -end; - - -procedure TBIFFGrid.ShowMulRK; -var - w: Word; - numBytes: Integer; - i, nc: Integer; - dw: DWord; - encint: DWord; - encdbl: QWord; - dbl: Double absolute encdbl; - s: String; -begin - nc := (Length(FBuffer) - 6) div 6; - RowCount := FixedRows + 3 + nc*2; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to row'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first column'); - - for i:=0 to nc-1 do begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - Format('Index to XF record #%d', [i])); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - - if Row = FCurrRow then begin - FDetails.Add('RK Value:'#13); - if dw and $00000001 = 0 - then FDetails.Add('Bit 0 = 0: Value not changed') - else FDetails.Add('Bit 0 = 1: Encoded value is multiplied by 100.'); - if dw and $00000002 = 0 - then FDetails.Add('Bit 1 = 0: Floating point value') - else FDetails.Add('Bit 1 = 1: Signed integer value'); - if dw and $00000002 = 0 then begin - encdbl := (QWord(dw) and QWord($FFFFFFFFFFFFFFFC)) shl 32; - if dw and $00000001 = 1 then - s := Format('%.2f', [dbl*0.01]) - else - s := Format('%.0f', [dbl]); - end - else begin - s := Format('$%.16x', [-59000000]); - encint := ((dw and DWord($FFFFFFFC)) shr 2) or (dw and DWord($C0000000)); - // "arithmetic shift" = replace left-most bits by original bits - if dw and $00000001 = 1 then - s := FloatToStr(encint*0.01) - else - s := IntToStr(encint); - end; - FDetails.Add('Bits 31-2: Encoded value ' + s); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, - Format('$%.8x', [dw]), - Format('RK value #%d', [i]) - ); - end; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to last column'); -end; - -procedure TBIFFGrid.ShowNote; -var - numBytes: Integer; - w: Word = 0; - s: String; -begin - RowCount := IfThen(FFormat = sfExcel8, 6, 5); - - // Offset 0: Row and Col index - ShowRowColData(FBufferIndex); - - if FFormat = sfExcel8 then begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Comment flags:'#13); - if (w and $0002 <> 0) - then FDetails.Add('x Bit 1=1: Comment is shown at all times') - else FDetails.Add(' Bit 1=0: Comment is not shown at all tiems'); - if (w and $0080 <> 0) - then FDetails.Add('x Bit 7=1: Row with comment is hidden') - else FDetails.Add(' Bit 7=0: Row with comment is visible'); - if (w and $0100 <> 0) - then FDetails.Add('x Bit 8=1: Column with comment is hidden') - else FDetails.Add(' Bit 8=0: Column with comment is visible'); - FDetails.Add('All other bits are reserved and must be ignored.'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Flags'); - - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Object ID'); - - ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8, - s, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Author'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Total length of comment'); - - numBytes := Min(Length(FBuffer) - FBufferIndex, 2048); - SetLength(s, numBytes); - Move(FBuffer[FBufferIndex], s[1], numBytes); - SetLength(s, Length(s)); - s := UTF8StringReplace(s, #10, '[\n]', [rfReplaceAll]); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Comment text'); - end; -end; - - -procedure TBIFFGrid.ShowNumberCell; -var - numBytes: Integer; - b: Byte = 0; - w: Word = 0; - dbl: Double; -begin - RowCount := IfThen(FFormat = sfExcel2, FixedRows + 6, FixedRows + 4); - // Offset 0: Row & Offsset 2: Column - ShowRowColData(FBufferIndex); - // Offset 4: Cell attributes (BIFF2) or XF ecord index (> BIFF2) - if FFormat = sfExcel2 then begin - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell protection and XF index:'#13); - FDetails.Add(Format('x Bits 5-0 = %d: XF Index', [b and $3F])); - case b and $40 of - 0: FDetails.Add(' Bit 6 = 0: Cell is NOT locked.'); - 1: FDetails.Add('x Bit 6 = 1: Cell is locked.'); - end; - case b and $80 of - 0: FDetails.Add(' Bit 7 = 0: Formula is NOT hidden.'); - 1: FDetails.Add('x Bit 7 = 1: Formula is hidden.'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Cell protection and XF index'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Indexes to format and font records:'#13); - FDetails.Add(Format('Bits 5-0 = %d: Index to FORMAT record', [b and $3f])); - FDetails.Add(Format('Bits 7-6 = %d: Index to FONT record', [(b and $C0) shr 6])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b,b]), - 'Indexes of format and font records'); - - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - if Row = FCurrRow then begin - FDetails.Add('Cell style:'#13); - case b and $07 of - 0: FDetails.Add('x Bits 2-0 = 0: Horizontal alignment is GENERAL'); - 1: FDetails.Add('x Bits 2-0 = 1: Horizontal alignment is LEFT'); - 2: FDetails.Add('x Bits 2-0 = 2: Horizontal alignment is CENTERED'); - 3: FDetails.Add('x Bits 2-0 = 3: Horizontal alignment is RIGHT'); - 4: FDetails.Add('x Bits 2-0 = 4: Horizontal alignment is FILLED'); - end; - if b and $08 = 0 - then FDetails.Add(' Bit 3 = 0: Cell has NO left border') - else FDetails.Add('x Bit 3 = 1: Cell has left black border'); - if b and $10 = 0 - then FDetails.Add(' Bit 4 = 0: Cell has NO right border') - else FDetails.Add('x Bit 4 = 1: Cell has right black border'); - if b and $20 = 0 - then FDetails.Add(' Bit 5 = 0: Cell has NO top border') - else FDetails.Add('x Bit 5 = 1: Cell has top black border'); - if b and $40 = 0 - then FDetails.Add(' Bit 6 = 0: Cell has NO bottom border') - else FDetails.Add('x Bit 6 = 1: Cell has bottom black border'); - if b and $80 = 0 - then FDetails.Add(' Bit 7 = 0: Cell has NO shaded background') - else FDetails.Add('x Bit 7 = 1: Cell has shaded background'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.2x)', [b,b]), - 'Cell style'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrROw, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Index of XF record'); - end; - // Offset 6: Double value - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%g', [dbl]), //FloatToStr(dbl), - 'IEEE 764 floating-point value'); -end; - - -procedure TBIFFGrid.ShowObj; -var - numBytes: Integer; - w: Word; - dw: DWord; - savedBufferIndex: Integer; - fieldType: Word; - fieldSize: Word; - s: String; - i, n: Integer; - guid: TGUID; -begin - if FFormat = sfExcel8 then begin - n := 0; - RowCount := FixedRows + 1000; - while FBufferIndex < Length(FBuffer) do begin - savedBufferIndex := FBufferIndex; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - fieldType := WordLEToN(w); - case fieldType of - $00: s := 'ftEnd (End of OBJ record)'; - $01: s := '(Reserved)'; - $02: s := '(Reserved)'; - $03: s := '(Reserved)'; - $04: s := 'ftMacro (fmla-style macro)'; - $05: s := 'ftButton (Command button)'; - $06: s := 'ftGmo (Group marker)'; - $07: s := 'ftCf (Clipboard format)'; - $08: s := 'ftPioGrbit (Picture option flags)'; - $09: s := 'ftPictFmla (Picture fmla-style macro)'; - $0A: s := 'ftCbls (Checkbox link)'; - $0B: s := 'ftRbo (Radio button)'; - $0C: s := 'ftSbs (Scrollbar)'; - $0D: s := 'ftNts (Note structure)'; - $0E: s := 'ftSbsFmla (Scroll bar fmla-style macro)'; - $0F: s := 'ftGboData (Group box data)'; - $10: s := 'ftEdoData (Edit control data)'; - $11: s := 'ftRboData (Radio button data)'; - $12: s := 'ftCblsData (Check box data)'; - $13: s := 'ftLbsData (List box data)'; - $14: s := 'ftCblsFmla (Check box link fmla-style macro)'; - $15: s := 'ftCmo (Common object data)'; - else s := '(unknown)'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.04x', [fieldType]), - Format('Subrecord type: %s', [s])); - inc(n); - - Move(FBuffer[FBufferIndex], w, numBytes); - fieldSize := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(fieldSize), 'Size of subrecord'); - inc(n); - - case fieldType of - $000D: - begin // ftNts, from https://msdn.microsoft.com/en-us/library/office/dd951373%28v=office.12%29.aspx - numBytes := 16; - Move(FBuffer[FBufferIndex], guid, numBytes); - s := GuidToString(guid); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'GUID of comment'); - inc(n); - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Shared Note (0 = false, 1 = true)'); - inc(n); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), - 'Unused (undefined, must be ignored)'); - inc(n); - end; - - $0015: - begin // common object data - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - case w of - $00: s := 'Group'; - $01: s := 'Line'; - $02: s := 'Rectangle'; - $03: s := 'Oval'; - $04: s := 'Arc'; - $05: s := 'Chart'; - $06: s := 'Text'; - $07: s := 'Button'; - $08: s := 'Picture'; - $09: s := 'Polybon'; - $0A: s := '(Reserved)'; - $0B: s := 'Checkbox'; - $0C: s := 'Option button'; - $0D: s := 'Edit box'; - $0E: s := 'Label'; - $0F: s := 'Dialog box'; - $10: s := 'Spinner'; - $11: s := 'Scrollbar'; - $12: s := 'List box'; - $13: s := 'Group box'; - $14: s := 'Combobox'; - $15: s := '(Reserved)'; - $16: s := '(Reserved)'; - $17: s := '(Reserved)'; - $18: s := '(Reserved)'; - $19: s := 'Comment'; - $1A: s := '(Reserved)'; - $1B: s := '(Reserved)'; - $1C: s := '(Reserved)'; - $1D: s := '(Reserved)'; - $1E: s := 'Microsoft Office drawing'; - else s := '(Unknown)'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.04x', [w]), - 'Object type: '+s); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.04x', [w]), - 'Object ID number'); - inc(n); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if w and $0001 <> 0 - then FDetails.Add('x Bit $0001 = 1: Object is locked when sheet is protected.') - else FDetails.Add(' Bit $0001 = 0: Object is NOT locked when sheet is protected.'); - if w and $000E <> 0 - then FDetails.Add('! Bit $0002 <> 0: Reserved - must be zero - THIS SEEMS TO BE AN ERROR!') - else FDetails.Add(' Bit $0002 = 0: Reserved - must be zero'); - if w and $0010 <> 0 - then FDetails.Add('x Bit $0010 = 1: Image of this object is intended to be included when printing') - else FDetails.Add(' Bit $0010 = 0: Image of this object is NOT intended to be included when printing'); - if w and $1FE0 <> 0 - then FDetails.Add('! Bits 12-5 <> 0: Reserved - must be zero - THIS SEEMS TO BE AN ERROR!') - else FDetails.Add(' Bits 12-5 = 0: Reserved - must be zero'); - if w and $2000 <> 0 - then FDetails.Add('x Bit $2000 = 1: Object uses automatic fill style.') - else FDetails.Add(' Bit $2000 = 0: Object does NOT use automatic fill style.'); - if w and $4000 <> 0 - then FDetails.Add('x Bit $4000 = 1: Object uses automatic line style.') - else FDetails.Add(' Bit $4000 = 0: Object does NOT use automatic line style.'); - if w and $8000 <> 0 - then FDetails.Add('! Bit $8000 = 1: Reserved - must be zero - THIS SEEMS TO BE AN ERROR!') - else FDetails.Add(' Bit $8000 = 0: Reserved - must be zero.'); - end; - s := ''; - if w and $0001 <> 0 then s := s + 'locked, '; - if w and $0010 <> 0 then s := s + 'print, '; - if w and $2000 <> 0 then s := s + 'automatic fill style, '; - if w and $4000 <> 0 then s := s + 'automatic line style, '; - if s <> '' then begin - Delete(s, Length(s)-1, 2); - s := 'Option flags:' + s; - end else - s := 'Option flags'; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.04x', [w]), s); - inc(n); - end; - end; - FBufferIndex := savedBufferIndex + 4 + fieldSize; - end; - RowCount := FixedRows + n; - end else - if FFormat = sfExcel5 then begin - // to do - end; -end; - - -procedure TBIFFGrid.ShowPageSetup; -var - numBytes: Integer; - w: Word; - s: String; - dbl: Double; -begin - if FFormat in [sfExcel5, sfExcel8] then RowCount := FixedRows + 11 - else RowCount := FixedRows + 6; - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Paper size:'#13); - FDetails.Add(Format('%d - %s', [w, PaperSizeName(w)])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Paper size'); - - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Scaling factor in percent'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLETON(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Start page number'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLETON(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Fit worksheet width to this number of pages (0 = use as many as needed)'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLETON(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Fit worksheet height to this number of pages (0 = use as many as needed)'); - - { Excel4 not supported in fpspreadsheet } - { - if FFormat = sfExcel4 then begin - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLETON(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if w and $0001 = 0 - then FDetails.Add('Bit $0001 = 0: Print pages in columns') - else FDetails.Add('Bit $0001 = 1: Print pages in rows'); - if w and $0002 = 0 - then FDetails.add('Bit $0002 = 0: Landscape') - else FDetails.Add('Bit $0002 = 1: Portrait'); - if w and $0004 = 0 - then FDetails.Add('Bit $0004 = 0: Paper size, scaling factor, and paper orientation ' + - '(portrait/landscape) ARE initialised') - else FDetails.Add('Bit $0004 = 1: Paper size, scaling factor, and paper orientation ' + - '(portrait/landscape) are NOT initialised'); - if w and $0008 = 0 - then FDetails.Add('Bit $0008 = 0: Print colored') - else FDetails.add('Bit $0008 = 1: Print black and white'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x (%d)', [w, w]), - 'Option flags'); - end else } - if (FFormat in [sfExcel5, sfExcel8]) then begin - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if w and $0001 = 0 - then FDetails.Add('Bit $0001 = 0: Print pages in columns') - else FDetails.Add('Bit $0001 = 1: Print pages in rows'); - if w and $0002 = 0 - then FDetails.add('Bit $0002 = 0: Landscape') - else FDetails.Add('Bit $0002 = 1: Portrait'); - if w and $0004 = 0 - then FDetails.Add('Bit $0004 = 0: Paper size, scaling factor, and paper orientation ' + - '(portrait/landscape) ARE initialised') - else FDetails.Add('Bit $0004 = 1: Paper size, scaling factor, and paper orientation ' + - '(portrait/landscape) are NOT initialised'); - if w and $0008 = 0 - then FDetails.Add('Bit $0008 = 0: Print colored') - else FDetails.add('Bit $0008 = 1: Print black and white'); - if w and $0010 = 0 - then FDetails.Add('Bit $0010 = 0: Default print quality') - else FDetails.Add('Bit $0010 = 1: Draft quality'); - if w and $0020 = 0 - then FDetails.Add('Bit $0020 = 0: Do NOT print cell notes') - else FDetails.Add('Bit $0020 = 0: Print cell notes'); - if w and $0040 = 0 - then FDetails.Add('Bit $0040 = 0: Use paper orientation (portrait/landscape) flag abov') - else FDetails.Add('Bit $0040 = 1: Use default paper orientation (landscape for chart sheets, portrait otherwise)'); - if w and $0080 = 0 - then FDetails.Add('Bit $0080 = 0: Automatic page numbers') - else FDetails.Add('Bit $0080 = 1: Use start page number above'); - if w and $0200 = 0 - then FDetails.Add('Bit $0200 = 0: Print notes as displayed') - else FDetails.Add('Bit $0200 = 1: Print notes at end of sheet'); - case (w and $0C00) shr 10 of - 0: FDetails.Add('Bit $0C00 = 0: Print errors as displayed'); - 1: FDetails.add('Bit $0C00 = 1: Do not print errors'); - 2: FDetails.Add('Bit $0C00 = 2: Print errors as "--"'); - 3: FDetails.Add('Bit $0C00 = 4: Print errors as "#N/A"'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x (%d)', [w, w]), - 'Option flags'); - - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Print resolution in dpi'); - - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Vertical print resolution in dpi'); - - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl), 'Header margin'); - - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl), 'Footer margin'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Number of copies to print'); - end; - -end; - -procedure TBIFFGrid.ShowPalette; -var - numBytes: Integer; - w: Word; - dw: DWord; - npal: Integer; - i: Integer; - s: String; -begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - npal := WordLEToN(w); - - RowCount := FixedRows + 1 + npal; - - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(npal), - 'Number of palette colors'); - - for i := 0 to npal-1 do begin - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - dw := DWordLEToN(dw); - s := Format('Palette color, index #%d ($%.2x)',[i, i]); - case i of - $00..$07: ; - $08..$3F: s := s + ', user-defined palette'; - $40 : s := s + ', system window text color for border lines'; - $41 : s := s + ', system window background color for pattern background'; - $43 : s := s + ', system face color (dialogue background color)'; - $4D : s := s + ', system window text colour for chart border lines'; - $4E : s := s + ', system window background color for chart areas'; - $4F : s := s + ', automatic color for chart border lines (seems to be always Black)'; - $50 : s := s + ', system tool tip background color (used in note objects)'; - $51 : s := s + ', system tool tip text color (used in note objects)'; - $7FFF : s := s + ', system window text color for fonts'; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.8x', [dw]), s); - end; -end; - - -procedure TBIFFGrid.ShowPane; -var - numBytes: Integer; - w: Word; - b: Byte; -begin - RowCount := FixedRows + IfThen(FFormat < sfExcel5, 5, 6); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Position of vertical split (twips or columns (if frozen))'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Position of horizontal split (twips or rows (if frozen))'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to first visible row in bottom pane(s)'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to first visible column in right pane(s)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(b), - 'Identifier of pane with active cell cursor'); - - if FFormat >= sfExcel5 then begin - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBUfferIndex, numBytes, IntToStr(b), 'not used'); - end; -end; - -procedure TBIFFGrid.ShowPassword; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Password verifier for sheet or workbook:'#13); - if w = 0 - then FDetails.Add('0 = No password') - else FDetails.Add(Format('$%.4x = Password verifier', [w])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Password verifier for sheet or workbook'); -end; - - -procedure TBIFFGrid.ShowPrecision; -var - numbytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Precision-as-displayed mode:'#13); - if w = 0 - then FDetails.Add('0 = Precision-as-displayed mode selected') - else FDetails.Add('1 = Precision-as-displayed mode NOT selected'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Precision-as-displayed mode'); -end; - - -procedure TBIFFGrid.ShowPrintGridLines; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Print sheet grid lines:'#13); - if w = 0 - then FDetails.Add('0 = Do not print sheet grid lines') - else FDetails.Add('1 = Print sheet grid lines'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Print sheet grid lines'); -end; - - -procedure TBIFFGrid.ShowPrintHeaders; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Print row/column headers'); - FDetails.Add('(the area with row numbers and column letters):'#13); - if w = 0 - then FDetails.Add('0 = Do not print row/column headers') - else FDetails.Add('1 = Print row/column headers'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Print row/column headers'); -end; - - -procedure TBIFFGrid.ShowProt4Rev; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Removal of the shared workbook''s revision logs:'#13); - if w = 0 - then FDetails.Add('0 = Removal of the shared workbook''s revision logs is allowed.') - else FDetails.Add('1 = Removal of the shared workbook''s revision logs is NOT allowed.'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Removal of the shared workbook''s revision logs'); -end; - - -procedure TBIFFGrid.ShowProt4RevPass; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Password verifier needed to change the PROT4REV record:'#13); - if w = 0 - then FDetails.Add('0 = No password.') - else FDetails.Add(Format('$%.04x = Password verifier.', [w])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w,w]), - 'Password verifier needed to change the PROT4REV record'); -end; - - -procedure TBIFFGrid.ShowProtect; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Protection state of the workbook:'#13); - if w = 0 - then FDetails.Add(' 0 = Workbook is NOT protected.') - else FDetails.Add('x 1 = Workbook is protected.'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'Protection state of the workbook'); -end; - - -procedure TBIFFGrid.ShowRecalc; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('"Recalculate before save" option:'#13); - if w = 0 - then FDetails.Add(' 0 = Do not recalculate') - else FDetails.Add('x 1 = Recalculate before saving the document'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Recalculate before saving'); -end; - - -procedure TBIFFGrid.ShowRefMode; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FbufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Cell reference mode:'#13); - if w = 0 - then FDetails.Add('0 = RC mode (i.e. cell address shown as "R(1)C(-1)"') - else FDetails.Add('1 = A1 mode (i.e. cell address shown as "B1")'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Cell reference mode'); -end; - - -procedure TBIFFGrid.ShowRefreshAll; -var - numbytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('RefreshAll record:'#13); - if w = 0 - then FDetails.Add(' 0 = Do not force refresh of external data ranges, PivotTables and XML maps on workbook load.') - else FDetails.Add('x 1 = Force refresh of external data ranges, PivotTables and XML maps on workbook load.'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w, w]), - 'Force refresh of external data ranges, Pivot tables and XML maps on workbook load'); -end; - - -procedure TBIFFGrid.ShowRightMargin; -var - numBytes: Integer; - dbl: Double; -begin - RowCount := FixedRows + 1; - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl), - 'Right page margin in inches (IEEE 754 floating-point value, 64-bit double precision)'); -end; - - -procedure TBIFFGrid.ShowRK; -var - numBytes: Integer; - w: Word; - dw: DWord; - encint: DWord; - encdbl: QWord; - dbl: Double absolute encdbl; - s: String; -begin - RowCount := FixedRows + 4; - - ShowRowColData(FBufferIndex); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to XF record'); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - dw := DWordLEToN(dw); - - if dw and $00000002 = 0 then begin - encdbl := (QWord(dw) and QWord($FFFFFFFFFFFFFFFC)) shl 32; - if dw and $00000001 = 1 then - s := Format('%.2f', [dbl*0.01]) - else - s := Format('%.0f', [dbl]); - end - else begin - s := Format('$%.16x', [-59000000]); - encint := ((dw and DWord($FFFFFFFC)) shr 2) or (dw and DWord($C0000000)); - // "arithmetic shift" = replace left-most bits by original bits - if dw and $00000001 = 1 then - s := FloatToStr(encint*0.01) - else - s := IntToStr(encint); - end; - - if Row = FCurrRow then begin - FDetails.Add('RK Value:'#13); - if dw and $00000001 = 0 - then FDetails.Add('Bit 0 = 0: Value not changed') - else FDetails.Add('Bit 0 = 1: Encoded value is multiplied by 100.'); - if dw and $00000002 = 0 - then FDetails.Add('Bit 1 = 0: Floating point value') - else FDetails.Add('Bit 1 = 1: Signed integer value'); - FDetails.Add('Bits 31-2: Encoded value ' + s); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, - Format('$%.8x', [QWord(dw)]), 'RK value ['+s+']'); -end; - - -procedure TBIFFGrid.ShowRow; -var - numBytes: Integer; - dw: DWord; - w: Word; - b: Byte; -begin - RowCount := FixedRows + IfThen(FFormat = sfExcel2, 10, 7); - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index of this row'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to column of the first cell which is described by a cell record'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to column of the last cell which is described by a cell record, increased by 1'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Row height:'#13); - FDetails.Add(Format('Bits 14-0 = %d: Row height in twips (1/20 pt) --> %.1f-pt', - [w and $7FFF, (w and $7FFF)/20.0]) - ); - if w and $8000 = 0 - then FDetails.Add('Bit 15 = 0: Row has custom height') - else FDetails.Add('Bit 15 = 1: Row has default height'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'Bits 14-0: Height of row in twips (1/20 pt), Bit 15: Row has default height'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, '', '(not used)'); - - if FFormat = sfExcel2 then begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - '0=No defaults written, 1=Default row attribute field and XF index occur below'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Relative offset to calculate stream position of the first cell record for this row'); - - if b = 1 then begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Cell protection and XF index'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Indexes to FORMAT and FONT records'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Cell style'); - end; - end - else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, '', - 'In BIFF5-BIFF8 this field is not used anymore, but the DBCELL record instead.'); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - if Row = FCurrRow then begin - FDetails.Add('Option flags and default row formatting:'#13); - FDetails.Add(Format('Bits 0-2 = %d: Outline level of the row', [dw and $00000007])); - if dw and $00000010 = 0 - then FDetails.Add('Bit 4 = 0: Outline group does not start or end here and is not collapsed') - else FDetails.Add('Bit 4 = 1: Outline group starts or ends here and is collapsed'); - if dw and $00000020 = 0 - then FDetails.Add('Bit 5 = 0: Row is NOT hidden') - else FDetails.Add('Bit 5 = 1: Row is hidden'); - if dw and $00000040 = 0 - then FDetails.Add('Bit 6 = 0: Row height and default font height do match.') - else FDetails.Add('Bit 6 = 1: Row height and default font height do NOT match.'); - if dw and $00000080 = 0 - then FDetails.Add('Bit 7 = 0: Row does NOT have explicit default format.') - else FDetails.Add('Bit 7 = 1: Row has explicit default format.'); - FDetails.Add('Bit 8 = 1: Is always 1'); - FDetails.Add(Format('Bits 16-27 = %d: Index to default XF record', [(dw and $0FFF0000) shr 16])); - if dw and $10000000 = 0 - then FDetails.Add('Bit 28 = 0: No additional space above the row.') - else FDetails.Add('Bit 28 = 1: Additional space above the row.'); - if dw and $20000000 = 0 - then FDetails.Add('Bit 29 = 0: No additional space below the row.') - else FDetails.Add('Bit 29 = 1: Additional space below the row.'); - if dw and $40000000 = 0 - then FDetails.Add('Bit 30 = 0: D0 NOT show phonetic text for all cells in the row.') - else FDetails.Add('Bit 30 = 1: Show phonetic text for all cells in the row.'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.8x', [dw]), - 'Option flags and default row formatting'); - end; -end; - -procedure TBIFFGrid.ShowRowColData(var ABufIndex: LongWord); -var - w: Word; - numBytes: Integer; -begin - // Row - numBytes := 2; - Move(FBuffer[ABufIndex], w, numBytes); - ShowInRow(FCurrRow, ABufIndex, numBytes, IntToStr(WordLEToN(w)), 'Index to row'); - // Column - numBytes := 2; - Move(FBuffer[ABufIndex], w, numBytes); - ShowInRow(FCurrRow, ABufIndex, numBytes, IntToStr(WordLEToN(w)), 'Index to column'); -end; - - -procedure TBIFFGrid.ShowRString; -var - numBytes: Integer; - b: Byte; - w: Word; - s: String; - len: Integer; - j: Integer; - wideStr: wideString; - ansiStr: ansiString; -begin - if FFormat < sfExcel5 then - exit; - - RowCount := FixedRows + 5; - - ShowRowColData(FBufferIndex); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]), - 'Index of XF record'); - - // String length - Move(FBuffer[FBufferIndex], w, 2); - len := WordLEToN(w); - - if FFormat = sfExcel8 then - begin - SetLength(widestr, len); - Move(FBuffer[FBufferIndex+3], widestr[1], len*2); - s := UTF8Encode(WideStringLEToN(widestr)); - numbytes := 3 + len*2; - end else - begin - SetLength(ansistr, len); - Move(FBuffer[FBufferIndex+2], ansistr[1], len); - s := AnsiToUTF8(ansistr); - numbytes := 2 + len; - end; - - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, - Format('%s string, 16-bit string length', [GetStringType])); - - // Number of rich-text formatting runs - numbytes := IfThen(FFormat = sfExcel8, 2, 1); - Move(FBuffer[FBufferIndex], w, numbytes); - len := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(len), - 'Count of rich-text formatting runs'); - - // Formatting run data - RowCount := RowCount + 2*len; - for j:=0 to len-1 do - begin - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - Format('Rich-Text formatting run #%d, index of first character', [j])); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - Format('Rich-Text formatting run #%d, font index', [j])); - end; -end; - - -procedure TBIFFGrid.ShowSelection; -var - numBytes: Integer; - w: word; - b: Byte; - i, n: Integer; -begin - Move(FBuffer[FBufferIndex+7], w, 2); - n := WordLEToN(w); - - RowCount := FixedRows + 5 + n*4; - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), 'Pane identifier (see PANE record)'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to row of the active cell'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to column of the active cell'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index into the following cell range list to the entry that contains the active cell'); - - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(n), - 'Number of following cell range addresses'); - - numbytes := 2; - for i:=1 to n do begin - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), 'Index to first row'); - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), 'Index to last row'); - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), 'Index to first column'); - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), 'Index to last column'); - end; -end; - - -procedure TBIFFGrid.ShowSharedFormula; -var - numBytes: Integer; - b: Byte; - w: Word; - tokenBytes: Integer; -begin - BeginUpdate; - RowCount := FixedRows + 1000; - // Brute force simplification because of unknown row count at this point - // Will be reduced at the end. - - // Index to first row - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), 'Index to first row'); - - // Index to last row - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), 'Index to last row'); - - // Index to first column - numBytes := 1; // 8-bit also for BIFF8! - Move(FBuffer[FBufferIndex], b, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), 'Index to first column'); - - // Index to last column - numBytes := 1; // 8-bit also for BIFF8! - Move(FBuffer[FBufferIndex], b, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), 'Index to last column'); - - // Not used - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), 'Not used'); - - // Number of existing FORMULA records for this shared formula - numBytes := 1; - Move(FBuffer[FBufferIndex], b, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), 'Number of FORMULA records in shared formula'); - - // Size of Token array (in Bytes) - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - tokenBytes := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(tokenBytes), - 'Size of formula data (in Bytes)'); - - // Formula tokens - ShowFormulaTokens(tokenBytes); - - RowCount := FCurrRow; - EndUpdate(true); -end; - - -procedure TBIFFGrid.ShowSheet; -var - numBytes: Integer; - dw: DWord; - b: Byte; - s: String; -begin - RowCount := FixedRows + 4; - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.8x)', [dw, dw]), - 'Absolute stream position of BOF record of sheet represented by this record.'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - 'Sheet state (0=visible, 1=hidden, 2="very" hidden)'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), - 'Sheet type ($00=worksheet, $02=Chart, $06=VB module)'); - - ExtractString(FBufferIndex, 1, (FFormat = sfExcel8), s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, IfThen(FFormat=sfExcel8, - 'Sheet name (unicode string, 8-bit string length)', - 'Sheet name (byte string, 8-bit string length)') - ); -end; - - -procedure TBIFFGrid.ShowSheetPR; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'#13); - if w and $0001 = 0 - then FDetails.Add(' Bit $0001 = 0: Do not show automatic page breaks') - else FDetails.Add('x Bit $0001 = 1: Show automatic page breaks'); - if w and $0010 = 0 - then FDetails.Add(' Bit $0010 = 0: Standard sheet') - else FDetails.Add('x Bit $0010 = 1: Dialog sheet (BIFF5-BIFF8)'); - if w and $0020 = 0 - then FDetails.Add(' Bit $0020 = 0: No automatic styles in outlines') - else FDetails.Add('x Bit $0020 = 1: Apply automatic styles to outlines'); - if w and $0040 = 0 - then FDetails.Add(' Bit $0040 = 0: Outline buttons above outline group') - else FDetails.Add('x Bit $0040 = 1: Outline buttons below outline group'); - if w and $0080 = 0 - then FDetails.Add(' Bit $0080 = 0: Outline buttons left of outline group') - else FDetails.Add('x Bit $0080 = 1: Outline buttons right of outline group'); - if w and $0100 = 0 - then FDetails.Add(' Bit $0100 = 0: Scale printout in percent') - else FDetails.Add('x Bit $0100 = 1: Fit printout to number of pages'); - if w and $0200 = 0 - then FDetails.Add(' Bit $0200 = 0: Save external linked values (BIFF3-BIFF4 only)') - else FDetails.Add('x Bit $0200 = 1: Do NOT save external linked values (BIFF3-BIFF4 only)'); - if w and $0400 = 0 - then FDetails.Add(' Bit $0400 = 0: Do not show row outline symbols') - else FDetails.Add('x Bit $0400 = 1: Show row outline symbols'); - if w and $0800 = 0 - then FDetails.Add(' Bit $0800 = 0: Do not show column outline symbols') - else FDetails.Add('x Bit $0800 = 1: Show column outline symbols'); - case (w and $3000) shr 12 of - 0: FDetails.Add('x Bits $3000 = $0000: Arrange windows tiled'); - 1: FDetails.Add('x Bits $3000 = $1000: Arrange windows horizontal'); - 2: FDetails.Add('x Bits $3000 = $2000: Arrange windows vertical'); - 3: FDetails.Add('x Bits $3000 = $3000: Arrange windows cascaded'); - end; - if w and $4000 = 0 - then FDetails.Add('x Bits $4000 = 0: Excel like expression evaluation (BIFF4-BIFF8 only)') - else FDetails.Add('x Bits $4000 = 1: Lotus like expression evaluation (BIFF4-BIFF8 only)'); - if w and $8000 = 0 - then FDetails.Add('x Bits $8000 = 0: Excel like formula editing (BIFF4-BIFF8 only)') - else FDetails.Add('x Bits $8000 = 1: Lotus like formula editing (BIFF4-BIFF8 only)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x (%d)', [w, w]), - 'Option flags'); -end; - -procedure TBIFFGrid.ShowSST; -var - numBytes: Integer; - s: String; - total1, total2: DWord; - i, j, n: Integer; - rtfRuns: TRichTextFormattingRuns; - rtfIndex: LongWord; - w: Word; -begin - numBytes := 4; - Move(FBuffer[FBufferIndex], total1, numBytes); - Move(FBuffer[FBufferIndex+4], total2, numBytes); - total1 := DWordLEToN(total1); - total2 := DWordLEToN(total2); - FTotalSST := total2; - - RowCount := FixedRows + 1000; - - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(total1), - 'Total number of shared strings in the workbook'); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(total2), - 'Number of following strings'); - - FPendingCharCount := -1; - n := 0; - for i:=1 to FTotalSST do begin - FCounterSST := i; - ExtractString(FBufferIndex, 2, true, s, numBytes, rtfRuns, rtfIndex); // BIFF8 only --> 2 length bytes - inc(n); - if FPendingCharCount = 0 then begin - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, IfThen(Length(rtfRuns) > 0, - Format('Shared string #%d (Count of Rich-Text formatting runs: %d)', [i, Length(rtfRuns)]), - Format('Shared string #%d', [i]))); -// ShowInRow(FCurrRow, FBufferIndex, numBytes, s, Format('Shared string #%d', [i])); - for j:=0 to High(rtfRuns) do - begin - ShowInRow(FCurrRow, rtfIndex, 2, IntToStr(rtfRuns[j].FirstIndex), - Format(' Rich-Text formatting run #%d, index of first character', [j])); - ShowInRow(FCurrRow, rtfIndex, 2, IntToStr(rtfRuns[j].FontIndex), - Format(' Rich-Text formatting run #%d, font index', [j])); - inc(n, 2); - end; - end - else - begin - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, Format('Shared string #%d - partial (--> CONTINUE)', [i])); - FInfo := BIFFNODE_SST_CONTINUE; - break; - end; - end; - RowCount := FixedRows + 2 + n; -end; - - -procedure TBIFFGrid.ShowStandardWidth; -var - w: Word; - numBytes: Integer; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d (%f characters)', [w, w/256]), - 'Default column width (overrides DFCOLWIDTH, in 1/256 of "0" width)'); -end; - - -procedure TBIFFGrid.ShowString; -var - numBytes: Integer; - s: String; -begin - RowCount := FixedRows + 1; - case FFormat of - sfExcel2: - begin - ExtractString(FBufferIndex, 1, false, s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Byte string, 8-bit string length'); - end; - sfExcel5: - begin - ExtractString(FBufferIndex, 2, false, s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Byte string, 16-bit string length'); - end; - sfExcel8: - begin - ExtractString(FBufferIndex, 2, true, s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Unicode string, 16-bit string length'); - end; - end; -end; - - -procedure TBIFFGrid.ShowStyle; -var - numBytes: Integer; - b: Byte; - w: Word; - s: String; - isRowLevel: Boolean; - isColLevel: Boolean; -begin - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if w and $8000 = 0 then - RowCount := FixedRows + 2 - else - RowCount := FixedRows + 3; - if Row = FCurrRow then begin - FDetails.Add('Style:'#13); - FDetails.Add(Format('Bits 0-11 = %d: Index to style XF record', [w and $0FFFF])); - if w and $8000 = 0 - then FDetails.Add('Bit 15 = 0: user-defined style') - else FDetails.Add('Bit 15 = 1: built-in style'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), 'Style index and type'); - - if w and $8000 = 0 then begin - if FFormat = sfExcel8 then begin - ExtractString(FBufferIndex, 2, true, s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Style name (Unicode string, 16-bit string length)'); - end else begin - ExtractString(FBufferIndex, 1, false, s, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'Style name (Byte string, 8-bit string length)'); - end; - end else begin - numbytes := 1; - b := FBuffer[FBufferIndex]; - isRowLevel := (b = 1); - isColLevel := (b = 2); - if FCurrRow = Row then begin - FDetails.Add('Identifier for built-in cell style:'#13); - case b of - 0: FDetails.Add('0 = normal'); - 1: FDetails.Add('1 = RowLevel (see next field)'); - 2: FDetails.Add('2 = ColLevel (see next field)'); - 3: FDetails.Add('3 = Comma'); - 4: FDetails.Add('4 = Currency'); - 5: FDetails.Add('5 = Percent'); - 6: FDetails.Add('6 = Comma [0]'); - 7: FDetails.Add('7 = Currency [0]'); - 8: FDetails.Add('8 = Hyperlink'); - 9: FDetails.Add('9 = Followed hyperlink'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Identifier for built-in cell style'); - - b := FBuffer[FBufferIndex]; - if FCurrRow = Row then begin - FDetails.Add('Level for RowLevel or ColLevel style (zero-based):'#13); - if b = $FF then - FDetails.Add('$FF = no RowLevel or ColLevel style') - else - if isRowLevel then - FDetails.Add('RowLevel = ' + IntToStr(b)) - else if isColLevel then - FDetails.Add('ColLevel = ' + IntToStr(b)); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - 'Level for RowLevel or ColLevel style (if available)'); - end; -end; - - -procedure TBIFFGrid.ShowStyleExt; -var - numBytes: Integer; - w: Word; - b: Byte; - bs: Byte; - s: String; -begin - RowCount := FixedRows + 11; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [wordLEToN(w)]), - 'Future record type'); - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Attributes:'#13); - if w and $0001 = 0 - then FDetails.Add(' Bit 0 = 0: The containing record does not specify a range of cells.') - else FDetails.Add('x Bit 0 = 1: The containing record specifies a range of cells.'); - FDetails.Add('Bit 1: specifies wether to alert the user of possible problems '+ - 'when saving the file whithout having reckognized this record.'); - FDetails.Add('Bits 2-15: reserved (MUST be zero, MUST be ignored)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), - 'Attributes'); - numbytes := 8; - ShowInRow(FCurrRow, FBufferIndex, numbytes, '', 'Reserved'); - - numbytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Flags:'#13); - if b and $01 = 0 - then FDetails.Add(' Bit 0 = 0: no built-in style') - else FDetails.Add('x Bit 0 = 1: built-in style'); - if b and $02 = 0 - then FDetails.Add(' Bit 1 = 0: NOT hidden') - else FDetails.Add('x Bit 1 = 1: hidden (i.e. is displayed in user interface)'); - FDetails.Add('Bit 2: specifies whether the built-in cell style was modified '+ - 'by the user and thus has a custom definition.'); - FDetails.Add('Bit 3-7: Reserved'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), 'Flags'); - - numbytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Category:'#13); - case b of - 0: FDetails.Add('Bits 0-7 = 0: Custom style'); - 1: FDetails.Add('Bits 0-7 = 1: Good, bad, neutral style'); - 2: FDetails.Add('Bits 0-7 = 2: Data model style'); - 3: FDetails.Add('Bits 0-7 = 3: Title and heading style'); - 4: FDetails.Add('Bits 0-7 = 4: Themed cell style'); - 5: FDetails.Add('Bits 0-7 = 5: Number format style'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), 'Category'); - - numbytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Built-in style:'#13); - FDetails.Add('An unsigned integer that specifies the type of the built-in cell style.'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), 'Built-in style'); - bs := b; - - numbytes := 1; - b := FBuffer[FBufferindex]; - if Row = FCurrRow then begin - FDetails.Add('Outline depth level:'#13); - FDetails.Add('An unsigned integer that specifies the depth level of row/column automatic outlining.'); - if (bs in [1, 2]) then - FDetails.Add(Format('Bits 0-7 = %d: Outline level is %d', [b, b+1])) - else - FDetails.Add(Format('Bits 0-7 = $%.2x: MUST be $FF, MUST be ignoried', [b])); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [b]), 'Outline depth level'); - - ExtractString(FBufferIndex, 1, true, s, numBytes, true); - ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Name of the style name to extend (Unicode string, 8-bit string length)'); - - numbytes := 2; - ShowInRow(FCurrRow, FBufferIndex, numbytes, '', 'XFProps (reserved)'); - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), 'Count of XFProp structures to follow in array'); - - -end; - - -procedure TBiffGrid.ShowTabID; -var - numbytes: Integer; - w: word; - i, n: Integer; -begin - numbytes := 2; - n := Length(FBuffer) div numbytes; - RowCount := FixedRows + n; - for i := 1 to n do begin - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w, w]), - 'Unique sheet identifier'); - end; -end; - - -procedure TBIFFGrid.ShowTopMargin; -var - numBytes: Integer; - dbl: Double; -begin - RowCount := FixedRows + 1; - numBytes := 8; - Move(FBuffer[FBufferIndex], dbl, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, FloatToStr(dbl), - 'Top page margin in inches (IEEE 754 floating-point value, 64-bit double precision)'); -end; - - -procedure TBIFFGrid.ShowTXO; -var - numbytes: Word; - w: Word; - s, sh, sv, sl: String; -begin - RowCount := FixedRows + 9; - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - sh := ''; - case (w and $000E) shr 1 of - 1: sh := sh + 'left-aligned, '; - 2: sh := sh + 'centered, '; - 3: sh := sh + 'right-aligned, '; - 4: sh := sh + 'justified, '; - end; - sv := ''; - case (w and $0070) shr 4 of - 1: sv := sv + 'top, '; - 2: sv := sv + 'middle, '; - 3: sv := sv + 'bottom, '; - 4: sv := sv + 'justify, '; - end; - s := sh + sv; - if (w and $0200) shr 9 <> 0 then s := s + 'lock text, '; - if Row = FCurrRow then begin - FDetails.Add( 'Option flags:'#13); - FDetails.Add( 'Bit 0: Reserved'); - if sh = '' then sh := 'none'; - FDetails.Add( 'Bits 1-3: 0 = Horizontal text alignment: ' + sh); - if sv = '' then sv := 'none'; - FDetails.Add( 'Bits 4-6: 0 = Vertical text alignment: ' + sv); - FDetails.Add( 'Bits 7-8: Reserved'); - case (w and $0200) shr 9 of - 0: FDetails.Add('Bit 9: Lock Text Option is off.'); - 1: FDetails.Add('Bit 9: Lock Text Option is on'); - end; - FDetails.Add( 'Bits 10-15: Reserved'); - end; - if s <> '' then begin - Delete(s, Length(s)-1, 2); - s := 'Option flags: ' + s; - end else - s := 'Option flags'; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), s); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - case w of - 0: s := 'No rotation (text appears left to right'; - 1: s := 'Text appears top to bottom; letters are upright'; - 2: s := 'Text is rotated 90 degrees counterclockwise'; - 3: s := 'Text is rotated 90 degrees clockwise'; - end; - if Row = FCurrRow then begin - FDetails.Add('Orientation of text with the object boundary:'#13); - FDetails.Add(Format('%d = %s', [w, s])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(w), - 'Orientation of text within the object boundary: ' + s); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Reserved (must be 0)'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Reserved (must be 0)'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Reserved (must be 0)'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Length (in characters) of text (in first following CONTINUE record)'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Length of formatting runs (in second following CONTINUE record)'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Reserved (must be 0)'); - - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Reserved (must be 0)'); -end; - -procedure TBIFFGrid.ShowWindow1; -var - numBytes: Word; - b: Byte; - w: word; -begin - RowCount := FixedRows + IfThen(FFormat < sfExcel5, 5, 9); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Horizontal position of the document window (in twips = 1/20 pt)'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Vertical position of the document window (in twips = 1/20 pt)'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Width of the document window (in twips = 1/20 pt)'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Height of the document window (in twips = 1/20 pt)'); - - if FFormat < sfExcel5 then begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(b)), - '0 = Window is visible; 1 = window is hidden'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'); - if w and $0001 = 0 - then FDetails.Add(' Bit $0001 = 0: Window is visible') - else FDetails.Add('x Bit $0001 = 1: Window is hidden'); - if w and $0002 = 0 - then FDetails.Add(' Bit $0002 = 0: Window is open') - else FDetails.Add('x Bit $0002 = 1: Window is minimized'); - if w and $0008 = 0 - then FDetails.Add(' Bit $0008 = 0: Horizontal scrollbar hidden') - else FDetails.Add('x Bit $0008 = 1: Horizontal scrollbar visible'); - if w and $0010 = 0 - then FDetails.Add(' Bit $0010 = 0: Vertical scrollbar hidden') - else FDetails.Add('x Bit $0010 = 1: Vertical scrollbar visible'); - if w and $0020 = 0 - then FDetails.Add(' Bit $0020 = 0: Worksheet tab bar hidden') - else FDetails.Add('x Bit $0020 = 1: Worksheet tab bar visible'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w, w]), - 'Option flags'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to active (displayed) worksheet'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index of first visible tab in the worksheet tab bar'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Number of selected worksheets (highlighted in the worksheet tab bar)'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Width of worksheet tab bar (in 1/1000 of window width). '+ - 'The remaining space is used by the horizontal scrollbar.'); - end; -end; - - -procedure TBIFFGrid.ShowWindow2; -var - numBytes: Word; - b: Byte; - w: word; - dw : DWord; -begin - if FFormat = sfExcel2 then begin - RowCount := FixedRows + 9; - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - '0 = Show formula results; 1 = Show formulas'); - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - '0 = Do not show grid lines; 1 = Show grid lines'); - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - '0 = Do not show sheet headers; 1 = Show sheet headers'); - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - '0 = Panes are not frozen; 1 = Panes are frozen'); - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - '0 = Show zero values as empty cells; 1 = Show zero values'); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first visible row'); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first visible column'); - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), - '0 = Use manual grid line colour (below); 1 = Use automatic grid line colour'); - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [DWordLEToN(dw)]), - 'Grid line RGB color'); - end else begin - RowCount := FixedRows + IfThen(FFormat = sfExcel5, 4, 8); - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Option flags:'); - if w and $0001 = 0 - then FDetails.Add(' Bit $0001 = 0: Show formula results') - else FDetails.Add('x Bit $0001 = 1: Show formulas'); - if w and $0002 = 0 - then FDetails.Add(' Bit $0002 = 0: Do not show grid lines') - else FDetails.Add('x Bit $0002 = 1: Show grid lines'); - if w and $0004 = 0 - then FDetails.Add(' Bit $0004 = 0: Do not show sheet headers') - else FDetails.Add('x Bit $0004 = 1: Show sheet headers'); - if w and $0008 = 0 - then FDetails.Add(' Bit $0008 = 0: Panes are not frozen') - else FDetails.Add('x Bit $0008 = 1: Panes are frozen'); - if w and $0010 = 0 - then FDetails.Add(' Bit $0010 = 0: Show zero values as empty cells') - else FDetails.Add('x Bit $0010 = 1: Show zero values'); - if w and $0020 = 0 - then FDetails.Add(' Bit $0020 = 0: Manual grid line color') - else FDetails.Add('x Bit $0020 = 1: Automatic grid line color'); - if w and $0040 = 0 - then FDetails.Add(' Bit $0040 = 0: Columns from left to right') - else FDetails.Add('x Bit $0040 = 1: Columns from right to left'); - if w and $0080 = 0 - then FDetails.Add(' Bit $0080 = 0: Do not show outline symbols') - else FDetails.Add('x Bit $0080 = 1: Show outline symbols'); - if w and $0100 = 0 - then FDetails.Add(' Bit $0100 = 0: Keep splits if pane freeze is removed') - else FDetails.Add('x Bit $0100 = 1: Remove splits if pane freeze is removed'); - if w and $0200 = 0 - then FDetails.Add(' Bit $0200 = 0: Sheet not selected') - else FDetails.Add('x Bit $0200 = 1: Sheet selected'); - if w and $0400 = 0 - then FDetails.Add(' Bit $0400 = 0: Sheet not active') - else FDetails.Add('x Bit $0400 = 1: Sheet active'); - if w and $0800 = 0 - then FDetails.Add(' Bit $0800 = 0: Show in normal view') - else FDetails.Add('x Bit $0800 = 1: Show in page break preview'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w, w]), - 'Option flags'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first visible row'); - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Index to first visible column'); - - if FFormat =sfExcel5 then begin - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [DWordLEToN(dw)]), - 'Grid line RGB color'); - end else begin - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Color index of grid line color'); - - ShowInRow(FCurrRow, FBufferIndex, numbytes, '', 'Not used'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Cached magnification factor in page break preview (in percent); 0 = Default (60%)'); - - Move(FBuffer[FBufferIndex], w, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(WordLEToN(w)), - 'Cached magnification factor in normal view (in percent); 0 = Default (100%)'); - - numBytes := 4; - ShowInRow(FCurrRow, FBufferIndex, numbytes, '', 'Not used'); - end; - end; -end; - - -procedure TBIFFGrid.ShowWindowProtect; -var - numBytes: Integer; - w: Word; -begin - RowCount := FixedRows + 1; - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Protection state of workbook windows:'#13); - if w = 0 - then FDetails.Add('0 = The workbook windows can be resized or moved and the window state can be changed.') - else FDetails.Add('1 = The workbook windows cannot be resized or moved and the window state cannot be changed.'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'Protection state of the workbook windows'); -end; - - -procedure TBIFFGrid.ShowWriteAccess; -var - numbytes: Integer; - s: String; -begin - RowCount := FixedRows + 1; - ExtractString(FBufferIndex, IfThen(FFormat=sfExcel8, 2, 1), FFormat=sfExcel8, s, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, s, 'User name (i.e., the name that you type when you install Microsoft Excel'); -end; - - -procedure TBIFFGrid.ShowWriteProt; -begin - RowCount := FixedRows + 2; - ShowInRow(FCurrRow, FBufferIndex, 0, '', 'Write protect: if present file is write-protected'); - ShowInRow(FCurrRow, FBufferIndex, 0, '', 'Write protection password is in FILESHARING record'); -end; - - -procedure TBIFFGrid.ShowXF; -var - numBytes: Word; - b: Byte; - w: word; - dw : DWord; -begin - if FFormat = sfExcel2 then begin - RowCount := FixedRows + 4; - numBytes := 1; - b := FBuffer[FBufferIndex]; - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(b), - 'Index to font record'); - ShowInRow(FCurrRow, FBufferIndex, numBytes, '', - '(not used)'); - - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Number format and cell flags:'#13); - FDetails.Add(Format('Bits 0-5 = %d: Index to FORMAT record', [b and $3F])); - if b and $40 = 0 - then FDetails.Add('Bit 6 = 0: Cell is not locked') - else FDetails.Add('Bit 6 = 1: Cell is locked'); - if b and $80 = 0 - then FDetails.Add('Bit 7 = 0: Formula is not hidden') - else FDetails.Add('Bit 7 = 1: Formula is hidden'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b, b]), - 'Number format and cell flags'); - - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Horizontal alignment, border style and background:'#13); - case b and $07 of - 0: FDetails.Add('Bits $07 = 0: Horizontal alignment "General"'); - 1: FDetails.Add('Bits $07 = 1: Horizontal alignment "Left"'); - 2: FDetails.Add('Bits $07 = 2: Horizontal alignemnt "Centered"'); - 3: FDetails.Add('Bits $07 = 3: Horizontal alignment "Right"'); - 4: FDetails.Add('Bits $07 = 4: Horizontal alignment "Filled"'); - 5: FDetails.Add('Bits $07 = 5: Horizontal alignment "Justified"'); - 6: FDetails.Add('Bits $07 = 6: Horizontal alignment "Centred across selection"'); - 7: FDetails.Add('Bits $07 = 7: Horizontal alignment "Distributed"'); - end; - if b and $08 = 0 - then FDetails.Add('Bit $08 = 0: Cell has no left border') - else FDetails.Add('Bit $08 = 1: Cell has left black border'); - if b and $10 = 0 - then FDetails.Add('Bit $10 = 0: Cell has no right border') - else FDetails.Add('Bit $10 = 1: Cell has right black border'); - if b and $20 = 0 - then FDetails.Add('Bit $20 = 0: Cell has no top border') - else FDetails.Add('Bit $20 = 1: Cell has top black border'); - if b and $40 = 0 - then FDetails.Add('Bit $40 = 0: Cell has no bottom border') - else FDetails.Add('Bit $40 = 1: Cell has bottom black border'); - if b and $80 = 0 - then FDetails.Add('Bit $80 = 0: Cell has no shaded background') - else FDetails.Add('Bit $80 = 1: Cell has shaded background'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), - 'Horizontal alignment, border style, and background'); - end - else - begin // XF (BIFF5 and BIFF8) - RowCount := FixedRows + IfThen(FFormat=sfExcel5, 7, 10); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to font record'); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - ShowInRow(FCurrRow, FBufferIndex, numBytes, IntToStr(WordLEToN(w)), - 'Index to format record'); - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('XFType, cell protection, parent style XF:'#13); - if w and $0001 = 0 - then FDetails.Add('Bit $0001 = 0: Cell is not locked') - else FDetails.Add('Bit $0001 = 1: Cell is locked'); - if w and $0002 = 0 - then FDetails.Add('Bit $0002 = 0: Formula is not hidden') - else FDetails.Add('Bit $0002 = 1: Formula is hidden'); - if w and $0004 = 0 - then FDetails.Add('Bit $0004 = 0: Cell XF') - else FDetails.Add('Bit $0004 = 1: Style XF'); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.4x', [w]), - 'XFType, cell protection, parent style XF'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Alignment and text break:'#13); - case b and $03 of - 0: FDetails.Add('Bits 0-2 = 0: Horizontal alignment "General"'); - 1: FDetails.Add('Bits 0-2 = 1: Horizontal alignment "Left"'); - 2: FDetails.Add('Bits 0-2 = 2: Horizontal alignemnt "Centered"'); - 3: FDetails.Add('Bits 0-2 = 3: Horizontal alignment "Right"'); - 4: FDetails.Add('Bits 0-2 = 4: Horizontal alignment "Filled"'); - 5: FDetails.Add('Bits 0-2 = 5: Horizontal alignment "Justified"'); - 6: FDetails.Add('Bits 0-2 = 6: Horizontal alignment "Centred across selection"'); - 7: if FFormat = sfExcel8 then - FDetails.Add('x Bits 0-2 = 7: Horizontal alignment "Distributed"'); - end; - if b and $08 = 0 - then FDetails.Add('Bit 3 = 0: Text is not wrapped.') - else FDetails.Add('Bit 3 = 1: Text is wrapped at right border.'); - case (b and $70) shr 4 of - 0: FDetails.Add('Bits 4-6 = 0: Vertical alignment "Top"'); - 1: FDetails.Add('Bits 4-6 = 1: Vertical alignment "Centered"'); - 2: FDetails.Add('Bits 4-6 = 2: Vertical alignment "Bottom"'); - 3: FDetails.Add('Bits 4-6 = 3: Vertical alignment "Justified"'); - 4: if FFormat = sfExcel8 then - FDetails.Add('Bits 4-6 = 4: Vertical alignment "Distributed"'); - end; - if FFormat = sfExcel8 then begin - if b and $80 = 0 - then FDetails.Add('Bit 3 = 0: Do NOT justify last line in justified or distibuted text') - else FDetails.Add('Bit 3 = 1: Justify last line in justified or distibuted text'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), - 'Alignment and text break'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - if FFormat = sfExcel5 then begin - if Row = FCurrRow then begin - FDetails.Add('Text orientation and flags for used attribute groups:'#13); - case (b and $03) of - 0: FDetails.Add('Bits $03 = 0: not rotated'); - 1: FDetails.Add('Bits $03 = 1: not rotated, letters stacked top-to-bottom'); - 2: FDetails.Add('Bits $03 = 2: text rotated 90° counter-clockwise'); - 3: FDetails.Add('Bits $03 = 3: text rotated 90° clockwise'); - end; - if b and $04 = 0 - then FDetails.Add('Bit $04 = 0: No flag for number format') - else FDetails.Add('Bit $04 = 1: Flag for number format'); - if b and $08 = 0 - then FDetails.Add('Bit $08 = 0: No flag for font') - else FDetails.Add('Bit $08 = 2: Flag for font'); - if b and $10 = 0 - then FDetails.Add('Bit $10 = 0: No flag for hor/vert alignment, text wrap, indentation, orientation, rotation, and text direction') - else FDetails.Add('Bit $10 = 1: Flag for hor/vert alignment, text wrap, indentation, orientation, rotation, and text direction'); - if b and $20 = 0 - then FDetails.Add('Bit $20 = 0: No flag for border lines') - else FDetails.Add('Bit $20 = 1: Flag for border lines'); - if b and $40 = 0 - then FDetails.Add('Bit $40 = 0: No flag for background area style') - else FDetails.Add('Bit $40 = 1: Flag for background area style'); - if b and $80 = 0 - then FDetails.Add('Bit $80 = 0: No flag for cell protection (cell locked and formula hidden)') - else FDetails.Add('Bit $80 = 1: Flag for cell protection (cell locked and formula hidden)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [b]), - 'Text orientation and flags for used attribute groups'); - end else - begin // sfExcel8 - if Row = FCurrRow then begin - FDetails.Add('Text rotation angle:'#13); - if b = 0 then - FDetails.Add('not rotated') - else if b <= 90 then - FDetails.Add(Format('%d degrees counter-clockwise', [b])) - else if b <= 180 then - FDetails.Add(Format('%d degrees clockwize', [b-90])) - else if b = 255 then - FDetails.Add('not rotated, letters stacked top-to-bottom'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(b), 'Text rotation angle'); - end; - - if FFormat = sfExcel8 then begin - numBytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Indentation, shrink to cell size, and text direction:'#13); - FDetails.Add(Format('Bits 0-3: Indent level = %d', [b and $0F])); - if b and $10 = 0 - then FDetails.Add('Bit $10 = 0: Don''t shrink content to fit into cell') - else FDetails.Add('Bit $10 = 1: Shrink content to fit into cell'); - if b and $20 = 0 - then FDetails.Add('Bit $20 = 0: Merge Cell option is OFF') - else FDetails.Add('Bit $20 = 1: Merge Cell option is ON'); - case (b and $C0) shr 6 of - 0: FDetails.Add('Bits 6-7 = 0: Text direction according to context'); - 1: FDetails.Add('Bits 6-7 = 1: Text direction left-to-right'); - 2: FDetails.Add('Bits 6-7 = 2: Text direction right-to-left'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [b]), - 'Indentation, shrink to cell size, and text direction'); - - numBytes := 1; - b := FBuffer[FBufferIndex]; - if Row = FCurrRow then begin - FDetails.Add('Flags for used attribute groups:'#13); - if b and $04 = 0 - then FDetails.Add('Bit $04 = 0: No flag for number format') - else FDetails.Add('Bit $04 = 1: Flag for number format'); - if b and $08 = 0 - then FDetails.Add('Bit $08 = 0: No flag for font') - else FDetails.Add('Bit $08 = 2: Flag for font'); - if b and $10 = 0 - then FDetails.Add('Bit $10 = 0: No flag for hor/vert alignment, text wrap, indentation, orientation, rotation, and text direction') - else FDetails.Add('Bit $10 = 1: Flag for hor/vert alignment, text wrap, indentation, orientation, rotation, and text direction'); - if b and $20 = 0 - then FDetails.Add('Bit $20 = 0: No flag for border lines') - else FDetails.Add('Bit $20 = 1: Flag for border lines'); - if b and $40 = 0 - then FDetails.Add('Bit $40 = 0: No flag for background area style') - else FDetails.Add('Bit $40 = 1: Flag for background area style'); - if b and $80 = 0 - then FDetails.Add('Bit $80 = 0: No flag for cell protection (cell locked and formula hidden)') - else FDetails.Add('Bit $80 = 1: Flag for cell protection (cell locked and formula hidden)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.2x', [b]), - 'Flags for used attribute groups'); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - if Row = FCurrRow then begin - FDetails.Add('Cell border lines and background area:'#13); - case dw and $0000000F of - $0000: FDetails.Add('Bits 0-3 = 0: Left border = No line'); - $0001: FDetails.Add('Bits 0-3 = 1: Left border = thin solid line'); - $0002: FDetails.Add('Bits 0-3 = 2: Left border = medium solid line'); - $0003: FDetails.Add('Bits 0-3 = 3: Left border = dashed line'); - $0004: FDetails.Add('Bits 0-3 = 4: Left border = dotted line'); - $0005: FDetails.Add('Bits 0-3 = 5: Left border = thick solid line'); - $0006: FDetails.Add('Bits 0-3 = 6: Left border = double solid line'); - $0007: FDetails.Add('Bits 0-3 = 7: Left border = hair line'); - $0008: FDetails.Add('Bits 0-3 = 8: Left border = medium dashed'); - $0009: FDetails.Add('Bits 0-3 = 9: Left border = thin dash-dotted'); - $000A: FDetails.Add('Bits 0-3 = 10: Left border = medium dash-dotted'); - $000B: FDetails.Add('Bits 0-3 = 11: Left border = thin dash-dot-dotted'); - $000C: FDetails.Add('Bits 0-3 = 12: Left border = medium dash-dot-dotted'); - $000D: FDetails.Add('Bits 0-3 = 13: Left border = slanted medium dash-dotted'); - end; - case dw and $000000F0 of - $0000: FDetails.Add('Bits 4-7 = 0: Right border = No line'); - $0010: FDetails.Add('Bits 4-7 = 1: Right border = thin solid line'); - $0020: FDetails.Add('Bits 4-7 = 2: Right border = medium solid line'); - $0030: FDetails.Add('Bits 4-7 = 3: Right border = dashed line'); - $0040: FDetails.Add('Bits 4-7 = 4: Right border = dotted line'); - $0050: FDetails.Add('Bits 4-7 = 5: Right border = thick solid line'); - $0060: FDetails.Add('Bits 4-7 = 6: Right border = double solid line'); - $0070: FDetails.Add('Bits 4-7 = 7: Right border = hair line'); - $0080: FDetails.Add('Bits 4-7 = 8: Right border = medium dashed'); - $0090: FDetails.Add('Bits 4-7 = 9: Right border = thin dash-dotted'); - $00A0: FDetails.Add('Bits 4-7 = 10: Right border = medium dash-dotted'); - $00B0: FDetails.Add('Bits 4-7 = 11: Right border = thin dash-dot-dotted'); - $00C0: FDetails.Add('Bits 4-7 = 12: Right border = medium dash-dot-dotted'); - $00D0: FDetails.Add('Bits 4-7 = 13: Right border = slanted medium dash-dotted'); - end; - case dw and $00000F00 of - $0000: FDetails.Add('Bits 8-11 = 0: Top border = No line'); - $0100: FDetails.Add('Bits 8-11 = 1: Top border = thin solid line'); - $0200: FDetails.Add('Bits 8-11 = 2: Top border = medium solid line'); - $0300: FDetails.Add('Bits 8-11 = 3: Top border = dashed line'); - $0400: FDetails.Add('Bits 8-11 = 4: Top border = dotted line'); - $0500: FDetails.Add('Bits 8-11 = 5: Top border = thick solid line'); - $0600: FDetails.Add('Bits 8-11 = 6: Top border = double solid line'); - $0700: FDetails.Add('Bits 8-11 = 7: Top border = hair line'); - $0800: FDetails.Add('Bits 8-11 = 8: Top border = medium dashed'); - $0900: FDetails.Add('Bits 8-11 = 9: Top border = thin dash-dotted'); - $0A00: FDetails.Add('Bits 8-11 = 10: Top border = medium dash-dotted'); - $0B00: FDetails.Add('Bits 8-11 = 11: Top border = thin dash-dot-dotted'); - $0C00: FDetails.Add('Bits 8-11 = 12: Top border = medium dash-dot-dotted'); - $0D00: FDetails.Add('Bits 8-11 = 13: Top border = slanted medium dash-dotted'); - end; - case dw and $0000F000 of - $0000: FDetails.Add('Bits 12-15 = 0: Bottom border = No line'); - $1000: FDetails.Add('Bits 12-15 = 1: Bottom border = thin solid line'); - $2000: FDetails.Add('Bits 12-15 = 2: Bottom border = medium solid line'); - $3000: FDetails.Add('Bits 12-15 = 3: Bottom border = dashed line'); - $4000: FDetails.Add('Bits 12-15 = 4: Bottom border = dotted line'); - $5000: FDetails.Add('Bits 12-15 = 5: Bottom border = thick solid line'); - $6000: FDetails.Add('Bits 12-15 = 6: Bottom border = double solid line'); - $7000: FDetails.Add('Bits 12-15 = 7: Bottom border = hair line'); - $8000: FDetails.Add('Bits 12-15 = 8: Bottom border = medium dashed'); - $9000: FDetails.Add('Bits 12-15 = 9: Bottom border = thin dash-dotted'); - $A000: FDetails.Add('Bits 12-15 = 10: Bottom border = medium dash-dotted'); - $B000: FDetails.Add('Bits 12-15 = 11: Bottom border = thin dash-dot-dotted'); - $C000: FDetails.Add('Bits 12-15 = 12: Bottom border = medium dash-dot-dotted'); - $D000: FDetails.Add('Bits 12-15 = 13: Bottom border = slanted medium dash-dotted'); - end; - FDetails.Add(Format('Bits 16-22 = %d: Color index for left line color', [(dw and $007F0000) shr 16])); - FDetails.Add(Format('Bits 23-29 = %d: Color index for right line color', [(dw and $3F800000) shr 23])); - if dw and $40000000 = 0 - then FDetails.Add('Bit 30 = 0: No diagonal line from top left to right bottom') - else FDetails.Add('Bit 30 = 1: Diagonal line from top left to right bottom'); - if dw and $80000000 = 0 - then FDetails.Add('Bit 31 = 0: No diagonal line from bottom left to right top') - else FDetails.Add('Bit 31 = 1: Diagonal line from bottom left to right top'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [dw]), - 'Cell border lines and background area'); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - if Row = FCurrRow then begin - FDetails.Add('Cell border lines and background area (cont''d):'#13); - FDetails.Add(Format('Bits 0-6 = %d: Color index for top line color', [(dw and $0000007F)])); - FDetails.Add(Format('Bits 7-13 = %d: Color index for bottom line color', [(dw and $00003F80) shr 7])); - FDetails.Add(Format('Bits 14-20 = %d: Color index for diagonal line color', [(dw and $001FC000) shr 14])); - case dw and $01E00000 shr 17 of - $0: FDetails.Add('Bits 21-24 = 0: Diagonal line style = No line'); - $1: FDetails.Add('Bits 21-24 = 1: Diagonal line style = thin solid line'); - $2: FDetails.Add('Bits 21-24 = 2: Diagonal line style = medium solid line'); - $3: FDetails.Add('Bits 21-24 = 3: Diagonal line style = dashed line'); - $4: FDetails.Add('Bits 21-24 = 4: Diagonal line style = dotted line'); - $5: FDetails.Add('Bits 21-24 = 5: Diagonal line style = thick solid line'); - $6: FDetails.Add('Bits 21-24 = 6: Diagonal line style = double solid line'); - $7: FDetails.Add('Bits 21-24 = 7: Diagonal line style = hair line'); - $8: FDetails.Add('Bits 21-24 = 8: Diagonal line style = medium dashed'); - $9: FDetails.Add('Bits 21-24 = 9: Diagonal line style = thin dash-dotted'); - $A: FDetails.Add('Bits 21-24 = 10: Diagonal line style = medium dash-dotted'); - $B: FDetails.Add('Bits 21-24 = 11: Diagonal line style = thin dash-dot-dotted'); - $C: FDetails.Add('Bits 21-24 = 12: Diagonal line style = medium dash-dot-dotted'); - $D: FDetails.Add('Bits 21-24 = 13: Diagonal line style = slanted medium dash-dotted'); - end; - case (dw and $FC000000) shr 26 of - $00: FDetails.Add('Bits 26-31 = 0: Fill pattern = No fill'); - $01: FDetails.Add('Bits 26-31 = 1: Fill pattern = solid fill'); - $02: FDetails.Add('Bits 26-31 = 2: Fill pattern = medium fill'); - $03: FDetails.Add('Bits 26-31 = 3: Fill pattern = dense fill'); - $04: FDetails.Add('Bits 26-31 = 4: Fill pattern = sparse fill'); - $05: FDetails.Add('Bits 26-31 = 5: Fill pattern = horizontal fill'); - $06: FDetails.Add('Bits 26-31 = 6: Fill pattern = vertical fill'); - $07: FDetails.Add('Bits 26-31 = 7: Fill pattern = backslash fill'); - $08: FDetails.Add('Bits 26-31 = 8: Fill pattern = slash fill'); - $09: FDetails.Add('Bits 26-31 = 9: Fill pattern = coarse medium fill'); - $0A: FDetails.Add('Bits 26-31 = 10: Fill pattern = coarse medium horiz fill'); - $0B: FDetails.Add('Bits 26-31 = 11: Fill pattern = sparse horizontal fill'); - $0C: FDetails.Add('Bits 26-31 = 12: Fill pattern = sparse vertical fill'); - $0D: FDetails.Add('Bits 26-31 = 13: Fill pattern = sparse backslash fill'); - $0E: FDetails.Add('Bits 26-31 = 14: Fill pattern = sparse slash fill'); - $0F: FDetails.Add('Bits 26-31 = 15: Fill pattern = cross fill'); - $10: FDetails.Add('Bits 26-31 = 16: Fill pattern = dense backslash fill'); - $11: FDetails.Add('Bits 26-31 = 17: Fill pattern = very sparse fill'); - $12: FDetails.Add('Bits 26-31 = 18: Fill pattern = extremely sparse fill'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [dw]), - 'Cell border lines and background area (cont''d)'); - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Cell border lines and background area (cont''d):'#13); - FDetails.Add(Format('Bits 0-6 = %d: Color index for pattern color', [(w and $007F)])); - FDetails.Add(Format('Bits 7-13 = %d: Color index for pattern background color', [(w and $3F80) shr 7])); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), - 'Cell border lines and background area (cont''d)'); - end; - - if FFormat = sfExcel5 then begin - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - dw := DWordLEToN(dw); - if Row = FCurrRow then begin - FDetails.Add('Cell border lines and background area:'#13); - FDetails.Add(Format('Bits 0-6 = %d: Color index for pattern color', [(dw and $007F)])); - FDetails.Add(Format('Bits 7-13 = %d: Color index for pattern background color', [(dw and $3F80) shr 7])); - case (dw and $003F0000) shr 16 of - $00: FDetails.Add('Bits 16-21 = 0: Fill pattern = No fill'); - $01: FDetails.Add('Bits 16-21 = 1: Fill pattern = solid fill'); - $02: FDetails.Add('Bits 16-21 = 2: Fill pattern = medium fill'); - $03: FDetails.Add('Bits 16-21 = 3: Fill pattern = dense fill'); - $04: FDetails.Add('Bits 16-21 = 4: Fill pattern = sparse fill'); - $05: FDetails.Add('Bits 16-21 = 5: Fill pattern = horizontal fill'); - $06: FDetails.Add('Bits 16-21 = 6: Fill pattern = vertical fill'); - $07: FDetails.Add('Bits 16-21 = 7: Fill pattern = backslash fill'); - $08: FDetails.Add('Bits 16-21 = 8: Fill pattern = slash fill'); - $09: FDetails.Add('Bits 16-21 = 9: Fill pattern = coarse medium fill'); - $0A: FDetails.Add('Bits 16-21 = 10: Fill pattern = coarse medium horiz fill'); - $0B: FDetails.Add('Bits 16-21 = 11: Fill pattern = sparse horizontal fill'); - $0C: FDetails.Add('Bits 16-21 = 12: Fill pattern = sparse vertical fill'); - $0D: FDetails.Add('Bits 16-21 = 13: Fill pattern = sparse backslash fill'); - $0E: FDetails.Add('Bits 16-21 = 14: Fill pattern = sparse slash fill'); - $0F: FDetails.Add('Bits 16-21 = 15: Fill pattern = cross fill'); - $10: FDetails.Add('Bits 16-21 = 16: Fill pattern = dense backslash fill'); - $11: FDetails.Add('Bits 16-21 = 17: Fill pattern = very sparse fill'); - $12: FDetails.Add('Bits 16-21 = 18: Fill pattern = extremely sparse fill'); - end; - case dw and $01C00000 shr 22 of - $0: FDetails.Add('Bits 22-24 = 0: Bottom line style = No line'); - $1: FDetails.Add('Bits 22-24 = 1: Bottom line style = thin solid line'); - $2: FDetails.Add('Bits 22-24 = 2: Bottom line style = medium solid line'); - $3: FDetails.Add('Bits 22-24 = 3: Bottom line style = dashed line'); - $4: FDetails.Add('Bits 22-24 = 4: Bottom line style = dotted line'); - $5: FDetails.Add('Bits 22-24 = 5: Bottom line style = thick solid line'); - $6: FDetails.Add('Bits 22-24 = 6: Bottom line style = double solid line'); - $7: FDetails.Add('Bits 22-24 = 7: Bottom line style = hair line'); - end; - FDetails.Add(Format('Bits 25-31 = %d: Color index for bottom line color', [(dw and $FE000000) shr 25])); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.8x', [dw]), - 'Cell border lines & background area'); - - numBytes := 4; - Move(FBuffer[FBufferIndex], dw, numBytes); - dw := DWOrdLEToN(dw); - if Row = FCurrRow then begin - FDetails.Add('Cell border lines (cont''d):'#13); - case dw and $00000007 of - $00: FDetails.Add('Bits 0-2 = 0: Top border = No line'); - $01: FDetails.Add('Bits 0-2 = 1: Top border = thin solid line'); - $02: FDetails.Add('Bits 0-2 = 2: Top border = medium solid line'); - $03: FDetails.Add('Bits 0-2 = 3: Top border = dashed line'); - $04: FDetails.Add('Bits 0-2 = 4: Top border = dotted line'); - $05: FDetails.Add('Bits 0-2 = 5: Top border = thick solid line'); - $06: FDetails.Add('Bits 0-2 = 6: Top border = double solid line'); - $07: FDetails.Add('Bits 0-2 = 7: Top border = hair line'); - end; - case (dw and $00000038) shr 3 of - $0000: FDetails.Add('Bits 3-5 = 0: Left border = No line'); - $0001: FDetails.Add('Bits 3-5 = 1: Left border = thin solid line'); - $0002: FDetails.Add('Bits 3-5 = 2: Left border = medium solid line'); - $0003: FDetails.Add('Bits 3-5 = 3: Left border = dashed line'); - $0004: FDetails.Add('Bits 3-5 = 4: Left border = dotted line'); - $0005: FDetails.Add('Bits 3-5 = 5: Left border = thick solid line'); - $0006: FDetails.Add('Bits 3-5 = 6: Left border = double solid line'); - $0007: FDetails.Add('Bits 3-5 = 7: Left border = hair line'); - end; - case (dw and $000001C0) shr 6 of - $0000: FDetails.Add('Bits 6-8 = 0: Right border = No line'); - $0010: FDetails.Add('Bits 6-8 = 1: Right border = thin solid line'); - $0020: FDetails.Add('Bits 6-8 = 2: Right border = medium solid line'); - $0030: FDetails.Add('Bits 6-8 = 3: Right border = dashed line'); - $0040: FDetails.Add('Bits 6-8 = 4: Right border = dotted line'); - $0050: FDetails.Add('Bits 6-8 = 5: Right border = thick solid line'); - $0060: FDetails.Add('Bits 6-8 = 6: Right border = double solid line'); - $0070: FDetails.Add('Bits 6-8 = 7: Right border = hair line'); - end; - FDetails.Add(Format('Bits 9-15 = %d: Color index for top line color', [(dw and $0000FE00) shr 7])); - FDetails.Add(Format('Bits 16-22 = %d: Color index for left line color', [(dw and $007F0000) shr 16])); - FDetails.Add(Format('Bits 23-29 = %d: Color index for right line color', [(dw and $3F800000) shr 23])); - end; - ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.8x', [dw]), - 'Cell border lines (cont''d)'); - end; - end; -end; - - -procedure TBIFFGrid.ShowXFCRC; -var - numBytes: Integer; - w: Word; - dw: DWord; -begin - RowCount := FixedRows + 7; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [wordLEToN(w)]), - 'Future record type'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Attributes:'#13); - if w and $0001 = 0 - then FDetails.Add(' Bit 0 = 0: The containing record does not specify a range of cells.') - else FDetails.Add('x Bit 0 = 1: The containing record specifies a range of cells.'); - FDetails.Add('Bit 1: specifies wether to alert the user of possible problems '+ - 'when saving the file whithout having reckognized this record.'); - FDetails.Add('Bits 2-15: reserved (MUST be zero, MUST be ignored)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), - 'Attributes'); - - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), 'Reserved'); - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), 'Reserved'); - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), 'Reserved'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Count of XF records'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w,w]), - 'Checksum of XF records'); -end; - - -procedure TBIFFGrid.ShowXFEXT; -var - numBytes: Integer; - w: Word; - dw: DWord; - i, n: Integer; - et: Word; - es: Word; - ct: Word; - buffidx: Cardinal; - s: String; -begin - BeginUpdate; - - RowCount := FixedRows + 100; - - numBytes := 2; - Move(FBuffer[FBufferIndex], w, numBytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [wordLEToN(w)]), - 'Future record type'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Attributes:'#13); - if w and $0001 = 0 - then FDetails.Add(' Bit 0 = 0: The containing record does not specify a range of cells.') - else FDetails.Add('x Bit 0 = 1: The containing record specifies a range of cells.'); - FDetails.Add('Bit 1: specifies wether to alert the user of possible problems '+ - 'when saving the file whithout having reckognized this record.'); - FDetails.Add('Bits 2-15: reserved (MUST be zero, MUST be ignored)'); - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), - 'Attributes'); - - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), 'Reserved'); - Move(FBuffer[FBufferIndex], dw, numbytes); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(DWordLEToN(dw)), 'Reserved'); - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), 'Reserved'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w,w]), - 'XF index'); - - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('$%.4x', [w]), 'Reserved'); - - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - 'Number of extension properties'); - n := w; - - for i:=1 to n do begin - buffidx := FBufferIndex; - numbytes := 2; - Move(FBuffer[FBufferIndex], et, numbytes); - et := WordLEToN(et); - if Row = FCurrRow then begin - FDetails.Add('Type:'#13); - case et of - $04: FDetails.Add('Full color extension that specifies the cell interior foreground color.'); - $05: FDetails.Add('Full color extension that specifies the cell interior background color.'); - $06: FDetails.Add('Gradient extension that specifies a cell interior gradient fill.'); - $07: FDetails.Add('Full color extension that specifies the top cell border color.'); - $08: FDetails.Add('Full color extension that specifies the bottom cell border color.'); - $09: FDetails.Add('Full color extension that specifies the left cell border color.'); - $0A: FDetails.Add('Full color extension that specifies the right cell border color.'); - $0B: FDetails.Add('Full color extension that specifies the diagonal cell border color.'); - $0D: FDetails.Add('Full color extension that specifies the cell text color.'); - $0E: FDetails.Add('2-byte unsigned integer that specifies a font scheme.'); - $0F: FDetails.Add('2-byte unsigned integer that specifies the text indentation level (MUST be <= 250).'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [et, et]), - Format('Extension property #%d: Type', [i])); - Move(FBuffer[FBufferIndex], es, numbytes); - es := WordLEToN(es); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(es), - Format('Extension property #%d: Data size', [i])); - - case et of - $04, $05, $07..$0D: // FullColorExt - begin - numbytes := 2; - Move(FBuffer[FBufferIndex], ct, numbytes); - ct := WordLEToN(ct); - if Row = FCurrRow then begin - FDetails.Add('Full color extension - Color type:'#13); - case ct of - 0: FDetails.Add('0 - Automatic color'); - 1: FDetails.Add('1 - Indexed color'); - 2: FDetails.Add('2 - RGB color'); - 3: FDetails.Add('3 - Theme color'); - 4: FDetails.Add('4 - Color not set'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(ct), - Format('Extension property #%d (Full color extension): Color type', [i])); - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(integer(w)), - Format('Extension property #%d (Full color extension): Color tint', [i])); - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - case ct of - 0: s := '(dummy - MUST be 0)'; - 1: s := '(index)'; - 2: s := '(RGB value)'; - 3: s := '(theme)'; - else s := ''; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.8x)', [QWord(dw), QWord(dw)]), - Format('Extension property #%d (Full color extension): value %s', [i, s])); - numbytes := 4; - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.8x)', [QWord(dw), QWord(dw)]), - Format('Extension property #%d (Full color extension): Reserved', [i])); - Move(FBuffer[FBufferIndex], dw, numbytes); - dw := DWordLEToN(dw); - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.8x)', [QWord(dw), QWord(dw)]), - Format('Extension property #%d (Full color extension): Reserved', [i])); - end; - - $06: // Gradient - begin - ShowInRow(FCurrRow, FBufferIndex, es, '(var)', - Format('Extension property #%d (Gradient): - not interpreted here -', [i])); - end; - - $0E: // Font scheme - begin - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - if Row = FCurrRow then begin - FDetails.Add('Font scheme:'#13); - case w of - 0: FDetails.Add('0 - No font scheme'); - 1: FDetails.Add('1 - Major scheme'); - 2: FDetails.Add('2 - Minor scheme'); - 3: FDetails.Add('3 - Ninched scheme'); - end; - end; - ShowInRow(FCurrRow, FBufferIndex, numbytes, Format('%d ($%.4x)', [w,w]), - Format('Extension property #%d Font scheme', [i])); - end; - - $0F: // Text indentation level - begin - numbytes := 2; - Move(FBuffer[FBufferIndex], w, numbytes); - w := WordLEToN(w); - ShowInRow(FCurrRow, FBufferIndex, numbytes, IntToStr(w), - Format('Extension property #%d Text indentation level', [i])); - end; - end; - FBufferIndex := buffidx + es; - end; - RowCount := FCurrRow; - - EndUpdate(true); -end; - - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/bebiffutils.pas b/components/fpspreadsheet/reference/BIFFExplorer/bebiffutils.pas deleted file mode 100644 index cc41ff108..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/bebiffutils.pas +++ /dev/null @@ -1,801 +0,0 @@ -unit beBIFFUtils; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils; - -function BOFName(ACode: Word): String; -function CodePageName(AID: Word): String; -function PaperSizeName(ACode: Word): String; -function RecTypeName(ARecType: Word): String; -function SheetFuncName(AIndex: Word): String; -function ErrorCodeName(ACode: Byte): String; - - -implementation - -function BOFName(ACode: Word): String; -begin - case ACode of - $0005: Result := 'Workbook globals'; - $0006: Result := 'Visual Basic module'; - $0010: Result := 'Sheet or dialog'; - $0020: Result := 'Chart'; - $0040: Result := 'Macro sheet'; - $0100: Result := 'Workspace'; - else Result := ''; - end; -end; - -function CodePageName(AID: Word): String; -begin - case AID of - $0016: Result := 'ASCII'; - $01B5: Result := 'IBM PC CP-437 (US)'; - $02D0: Result := 'IBM PC CP-720 (OEM Arabic)'; - $02E1: Result := 'IBM PC CP-737 (Greek)'; - $0307: Result := 'IBM PC CP-775 (Baltic)'; - $0352: Result := 'IBM PC CP-850 (Latin I)'; - $0354: Result := 'IBM PC CP-852 (Latin II (Central European))'; - $0357: Result := 'IBM PC CP-855 (Cyrillic)'; - $0359: Result := 'IBM PC CP-857 (Turkish)'; - $035A: Result := 'IBM PC CP-858 (Multilingual Latin I with Euro)'; - $035C: Result := 'IBM PC CP-860 (Portuguese)'; - $035D: Result := 'IBM PC CP-861 (Icelandic)'; - $035E: Result := 'IBM PC CP-862 (Hebrew)'; - $035F: Result := 'IBM PC CP-863 (Canadian (French))'; - $0360: Result := 'IBM PC CP-864 (Arabic)'; - $0361: Result := 'IBM PC CP-865 (Nordic)'; - $0362: Result := 'IBM PC CP-866 (Cyrillic (Russian))'; - $0365: Result := 'IBM PC CP-869 (Greek (Modern))'; - $036A: Result := 'Windows CP-874 (Thai)'; - $03A4: Result := 'Windows CP-932 (Japanese Shift-JIS)'; - $03A8: Result := 'Windows CP-936 (Chinese Simplified GBK)'; - $03B5: Result := 'Windows CP-949 (Korean (Wansung))'; - $03B6: Result := 'Windows CP-950 (Chinese Traditional BIG5)'; - $04B0: Result := 'UTF-16 (BIFF8)'; - $04E2: Result := 'Windows CP-1250 (Latin II) (Central European)'; - $04E3: Result := 'Windows CP-1251 (Cyrillic)'; - $04E4: Result := 'Windows CP-1252 (Latin I) (BIFF4-BIFF5)'; - $04E5: Result := 'Windows CP-1253 (Greek)'; - $04E6: Result := 'Windows CP-1254 (Turkish)'; - $04E7: Result := 'Windows CP-1255 (Hebrew)'; - $04E8: Result := 'Windows CP-1256 (Arabic)'; - $04E9: Result := 'Windows CP-1257 (Baltic)'; - $04EA: Result := 'Windows CP-1258 (Vietnamese)'; - $0551: Result := 'Windows CP-1361 (Korean (Johab))'; - $2710: Result := 'Apple Roman'; - $8000: Result := 'Apple Roman'; - $8001: Result := 'Windows CP-1252 (Latin I) (BIFF2-BIFF3)'; - else Result := ''; - end; -end; - -function ErrorCodeName(ACode: Byte): String; -begin - case ACode of - $00: Result := '#NULL! - Intersection of two cell ranges is empty'; - $07: Result := '#DIV/0! - Division by zero'; - $0F: Result := '#VALUE! - Wrong type of operand'; - $17: Result := '#REF! - Illegal or deleted cell reference'; - $1D: Result := '#NAME? - Wrong function or range name'; - $24: Result := '#NUM! - Value range overflow'; - $2A: Result := '#N/A - Argument or function not available'; - else Result := '(unknown)'; - end; -end; - - -function PaperSizeName(ACode: Word): String; -begin - case ACode of - 0: Result := 'Undefined'; - 1: Result := 'Letter (8.5" x 11")'; - 2: Result := 'Letter small (8.5" x 11")'; - 3: Result := 'Tabloid (11" x 17")'; - 4: Result := 'Ledger (17" x 11")'; - 5: Result := 'Legal (8.5" x 14")'; - 6: Result := 'Statement (5.5" x 8.5")'; - 7: Result := 'Executive (7.25" x 10.5")'; - 8: Result := 'A3 (297mm x 420mm)'; - 9: Result := 'A4 (210mm x 297mm)'; - 10: Result := 'A4 small (210mm x 297mm)'; - 11: Result := 'A5 (148mm x 210mm)'; - 12: Result := 'B4 (JIS) (257mm x 364mm)'; - 13: Result := 'B5 (JIS) (182mm x 257mm)'; - 14: Result := 'Folio (8.5" x 13")'; - 15: Result := 'Quarto (215mm x 275mm)'; - 16: Result := '10x14 (10" x 14")'; - 17: Result := '11x17 (11" x 17")'; - 18: Result := 'Note (8.5" x 11")'; - 19: Result := 'Envelope #9 (3 7/8" x 8 7/8")'; - 20: Result := 'Envelope #10 (4 1/8" x 9 1/2")'; - 21: Result := 'Envelope #11 (4 1/2" x 10 3/8")'; - 22: Result := 'Envelope #12 (4 3/4" x 11")'; - 23: Result := 'Envelope #14 (5" x 11.5")'; - 24: Result := 'C (17" x 22")'; - 25: Result := 'D (22" x 34")'; - 26: Result := 'E (34" x 44")'; - 27: Result := 'Envelope DL (110mm x 220mm)'; - 28: Result := 'Envelope C5 (162mm x 229mm)'; - 29: Result := 'Envelope C3 (324mm x 458mm)'; - 30: Result := 'Envelope C4 (229mm x 324mm)'; - 31: Result := 'Envelope C6 (114mm x 162mm)'; - 32: Result := 'Envelope C6/C5 (114mm x 229mm)'; - 33: Result := 'B4 (ISO) (250mm x 353mm)'; - 34: Result := 'B5 (ISO) (176mm x 250mm)'; - 35: Result := 'B6 (ISO) (125mm x 176mm)'; - 36: Result := 'Envelope Italy (110mm x 230mm)'; - 37: Result := 'Envelope Monarch (3 7/8" x 7 1/2")'; - 38: Result := '6 3/4 Envelope (3 5/8" x 6 1/2")'; - 39: Result := 'US Standard Fanfold (14 7/8" x 11")'; - 40: Result := 'German Std. Fanfold (8.5" x 12")'; - 41: Result := 'German Legal Fanfold (8.5" x 13")'; - 42: Result := 'B4 (ISO) (250mm x 353mm)'; - 43: Result := 'Japanese Postcard (100mm x 148mm)'; - 44: Result := '9x11 (9" x 11")'; - 45: Result := '10x11 (10" x 11")'; - 46: Result := '15x11 (15" x 11")'; - 47: Result := 'Envelope Invite (220mm x 220mm)'; - 48: Result := 'Undefined'; - 49: Result := 'Undefined'; - 50: Result := 'Letter Extra (9.5" x 12")'; - 51: Result := 'Legal Extra (9.5" x 15")'; - 52: Result := 'Tabloid Extra (11 11/16" x 18")'; - 53: Result := 'A4 Extra (235mm x 322mm)'; - 54: Result := 'Letter Transverse (8.5" x 11")'; - 55: Result := 'A4 Transverse (210mm x 297mm)'; - 56: Result := 'Letter Extra Transv. (9.5" x 12")'; - 57: Result := 'Super A/A4 (227mm x 356mm)'; - 58: Result := 'Super B/A3 (305mm x 487mm)'; - 59: Result := 'Letter Plus (8.5" x 12 11/16")'; - 60: Result := 'A4 Plus (210mm x 330mm)'; - 61: Result := 'A5 Transverse (148mm x 210mm)'; - 62: Result := 'B5 (JIS) Transverse (182mm x 257mm)'; - 63: Result := 'A3 Extra (322mm x 445mm)'; - 64: Result := 'A5 Extra (174mm x 235mm)'; - 65: Result := 'B5 (ISO) Extra (201mm x 276mm)'; - 66: Result := 'A2 (420mm s 594mm)'; - 67: Result := 'A3 Transverse (297mm x 420mm)'; - 68: Result := 'A3 Extra Transverse (322mm x 445mm)'; - 69: Result := 'Dbl. Japanese Postcard (200mm x 148mm)'; - 70: Result := 'A6 (105mm x 148mm)'; - 75: Result := 'Letter Rotated (11" x 8.5")'; - 76: Result := 'A3 Rotated (420mm x 297mm)'; - 77: Result := 'A4 Rotated (297mm x 210mm)'; - 78: Result := 'A5 Rotated (210mm x 148mm)'; - 79: Result := 'B4 (JIS) Rotated (364mm x 257mm)'; - 80: Result := 'B5 (JIS) Rotated (257mm x 182mm)'; - 81: Result := 'Japanese Postcard Rot. (148mm x 100mm)'; - 82: Result := 'Dbl. Jap. Postcard Rot. (148mm x 200mm)'; - 83: Result := 'A6 Rotated (148mm x 105mm)'; - 88: Result := 'B6 (JIS) (128mm x 182mm)'; - 89: Result := 'B6 (JIS) Rotated (182mm x 128mm)'; - 90: Result := '2x11 (12" x 11")'; - else Result := '(unknown)'; - end; -end; - -function RecTypeName(ARecType: Word): String; -begin - case ARecType of - $0000: Result := 'DIMENSION'; - $0001: Result := 'BLANK'; - $0002: Result := 'INTEGER'; - $0003: Result := 'NUMBER'; - $0004: Result := 'LABEL'; - $0005: Result := 'BoolErr'; - $0006: Result := 'FORMULA'; - $0007: Result := 'STRING'; - $0008: Result := 'ROW'; - $0009: Result := 'BOF: Begin of file'; - $000A: Result := 'EOF: End of file'; - $000B: Result := 'INDEX'; - $000C: Result := 'CALCCOUNT: Iteration count'; - $000D: Result := 'CALCMODE: Calculation mode'; - $000E: Result := 'PRECISION: Precision'; - $000F: Result := 'REFMODE: Reference mode'; - $0010: Result := 'DELTA: Iteration increment'; - $0011: Result := 'ITERATION: Iteration mode'; - $0012: Result := 'PROTECT: Protection flag'; - $0013: Result := 'PASSWORD: Protection password'; - $0014: Result := 'HEADER: Print header on each page'; - $0015: Result := 'FOOTER: Print footer on each page'; - $0016: Result := 'EXTERNCOUNT: Number of external references'; - $0017: Result := 'EXTERNSHEET: External reference'; - $0018: Result := 'DEFINEDNAME: Name and token array of an internal defined name'; - $0019: Result := 'WINDOWPROTECT: Windows are protected'; - $001A: Result := 'VERTICALPAGEBREAKS: Explicit column page breaks'; - $001B: Result := 'HORIZONALPAGEBREAKS: Explicit row page breaks'; - $001C: Result := 'NOTE: Comment associated with a cell'; - $001D: Result := 'SELECTION: Current selection'; - $001E: Result := 'FORMAT: Number format record'; - $001F: Result := 'FORMATCOUNT: Count of number formats'; - $0020: Result := 'ColumnDefault'; - $0021: Result := 'Array'; - $0022: Result := '1904: 1904 date system'; - $0023: Result := 'ExternalName'; - $0024: Result := 'COLWIDTH'; - $0025: Result := 'DefaultRowHeight'; - $0026: Result := 'LEFTMARGIN: Left margin measurement'; - $0027: Result := 'RIGHTMARGIN: Right margin measurement'; - $0028: Result := 'TOPMARGIN: Top margin measurement'; - $0029: Result := 'BOTTOMMARGIN: Bottom margin measurement'; - $002A: Result := 'PRINTHEADERS: Print row/column labels'; - $002B: Result := 'PRINTGRIDLINES: Print gridlines flag'; - $002F: Result := 'FILEPASS: File is password-protected'; - $0031: Result := 'FONT: Font and font formatting information'; - $0032: Result := 'FONT2'; - $0033: Result := 'PRINTSIZE: Printed size of chart'; - $0036: Result := 'DataTable'; - $0037: Result := 'DateTable2'; - $003C: Result := 'CONTINUE: Continues long records'; - $003D: Result := 'WINDOW1: Window information'; - $003E: Result := 'WINDOW2: Window information'; - $0040: Result := 'BACKUP: Save backup version of the file'; - $0041: Result := 'PANE: Number of panes and their position'; - $0042: Result := 'CODEPAGE: Default code page'; // also: CODENAME: VBE object name ??? - $0043: Result := 'XF: Extended format'; - $0044: Result := 'IXFE'; - $0045: Result := 'FONTCOLOR'; - $004D: Result := 'PLS: Environment-specific print record'; - $0050: Result := 'DCON: Data consolidation information'; - $0051: Result := 'DCONREF: Data consolidation references'; - $0055: Result := 'DEFCOLWIDTH: Default width for columns'; - $0056: Result := 'BuiltInFmtCount'; - $0059: Result := 'XCT: CRN record count'; - $005A: Result := 'CRN: Non-resident operands'; - $005B: Result := 'FILESHARING: File-sharing information'; - $005C: Result := 'WRITEACCESS: Write access user name'; - $005D: Result := 'OBJ: Properties of an object in a sheet'; - $005E: Result := 'UNCALCED: Recalculation status'; - $005F: Result := 'SAVERECALC: Recalculate before saving'; - $0060: Result := 'TEMPLATE: Workbook is a template'; - $0063: Result := 'OBJPROTECT: Objects are protected'; - $007D: Result := 'COLINFO: Column formatting information'; - $007E: Result := 'RK: Cell value, RK number'; - $007F: Result := 'IMDATA: Image data'; - $0080: Result := 'GUTS: Size of row and column gutters'; - $0081: Result := 'SHEETPR: Additional workspace information'; - $0082: Result := 'GRIDSET: State change of Gridlines option'; - $0083: Result := 'HCENTER: Center between horizontal margins'; - $0084: Result := 'VCENTER: Center between vertical margins'; - $0085: Result := 'BOUNDSSHEET: Sheet information'; - $0086: Result := 'WRITEPROT: Workbook is write-protected'; - $0087: Result := 'ADDIN: Workbook is an add-in macro'; - $0088: Result := 'EDG: Edition globals'; - $0089: Result := 'PUB: Publisher'; - $008C: Result := 'COUNTRY: Default country and WIN.INI country'; - $008D: Result := 'HIDEOBJ: Object display options'; - $0090: Result := 'SORT: Sorting options'; - $0091: Result := 'SUB: Subscriber'; - $0092: Result := 'PALETTE: Color palette definition'; - $0094: Result := 'LHRECORD: .WK? file conversion information'; - $0095: Result := 'LHNGRAPH: Named graph information'; - $0096: Result := 'SOUND: Sound note'; - $0098: Result := 'LPR: Sheet was printed using LINE.PRINT()'; - $0099: Result := 'STANDARDWIDTH: Standard column width'; - $009A: Result := 'FNGROUPNAME: Function group name'; - $009B: Result := 'FILTERMODE: Sheet contains filtered list'; - $009C: Result := 'FNGROUPCOUNT: Built-in function group count'; - $009D: Result := 'AUTOFILTERINFO: Drop-down arrow count'; - $009E: Result := 'AUTOFILTER: AutoFilter data'; - $00A0: Result := 'SCL: Window zoom magnification'; - $00A1: Result := 'PAGESETUP: PageSetup'; - $00A9: Result := 'COORDLIST: Polygon object vertex coordinates'; - $00AB: Result := 'GCW: Global column width flags'; - $00AE: Result := 'SCENMAN: Scenario output data'; - $00AF: Result := 'SCENARIO: Scenario data'; - $00B0: Result := 'SXVIEW: View definition'; - $00B1: Result := 'SXVD: View fields'; - $00B2: Result := 'SXVI: View item'; - $00B4: Result := 'SXIVD: Row/column field IDs'; - $00B5: Result := 'SXLI: Line item array'; - $00B6: Result := 'SXPI: Page item'; - $00B8: Result := 'DOCROUTE: Routing slip information'; - $00B9: Result := 'RECIPNAME: Recipient name'; - $00BC: Result := 'SHRFMLA: Shared formula'; - $00BD: Result := 'MULRK: Multiple RK cells'; - $00BE: Result := 'MULBLANK: Multiple blank cells'; - $00C1: Result := 'MMS: ADDMENU/DELMENU record group count'; - $00C2: Result := 'ADDMENU: Menu addition'; - $00C3: Result := 'DELMENU: Menu deletion'; - $00C5: Result := 'SXDI: Data item'; - $00C6: Result := 'SXDB: Pivot table cache data'; - $00CD: Result := 'SXSTRING: String'; - $00D0: Result := 'SXTBL: Multiple consolidation source info'; - $00D1: Result := 'SXBRGIITM: Page item name count'; - $00D2: Result := 'SXTBPG: Page item indexex'; - $00D3: Result := 'OBPROJ: Visual Basic project'; - $00D5: Result := 'SXIDSTM: Stream ID'; - $00D6: Result := 'RSTRING: Cell with character formatting'; - $00D7: Result := 'DBCELL: Stream offsets'; - $00DA: Result := 'BOOKBOOL: Workbook option flag'; - $00DC: Result := 'PARAMQRY: Query parameters'; // also: SXEXT: External source information - $00DD: Result := 'SCENPROTECT: Scenario Protection'; - $00DE: Result := 'OLESIZE: Size of OLE object'; - $00DF: Result := 'UDDESC: Description format for chart autoformat'; - $00E0: Result := 'XF: Extended format'; - $00E1: Result := 'INTERFACEHDR: Beginning of user interface records'; - $00E2: Result := 'INTERFACEEND: End of user interface records'; - $00E3: Result := 'SXVS: View source'; - $00E5: Result := 'MERGEDCELLS: List of merged cells'; - $00E9: Result := 'Bitmap'; - $00EA: Result := 'TABIDCONF: Sheet Tab ID of conflict history'; - $00EB: Result := 'MSODRAWINGGROUP: Microsoft Office drawing group'; - $00EC: Result := 'MSODRAWING: Microsoft Office drawing'; - $00ED: Result := 'MSODRAWINGSELECTION: Microsoft Office drawing selection'; - $00EF: Result := 'PhoneticPR'; - $00F0: Result := 'SXRULE: PivotTable rule data'; - $00F1: Result := 'SXEX: PivotTable view extended information'; - $00F2: Result := 'SXFILT: PivotTable rule filter'; - $00F4: Result := 'SXDXF: PivotTable formatting'; - $00F5: Result := 'SXITM: PivotTable item indexes'; - $00F6: Result := 'SXNAME: PivotTable name'; - $00F7: Result := 'SXSELECT: PivotTable selection information'; - $00F8: Result := 'SXPAIR: PivotTable name pair'; - $00F9: Result := 'SXFMLA: PivotTable parsed expression'; - $00FB: Result := 'SXFORMAT: PivotTable format record'; - $00FC: Result := 'SST: Shared string table'; - $00FD: Result := 'LABELSST: Cell value, string constant/SST'; - $00FF: Result := 'EXTSST: extended shared string table'; - $013D: Result := 'TABID: Sheet tab index array'; - $015F: Result := 'LabelRanges'; - $0160: Result := 'USESELFS: Natural language formulas flag'; - $0161: Result := 'DSF: Double stream file'; - $0162: Result := 'XL5MODIFY: Flag for DSF'; - $01AE: Result := 'EXTERNBOOK (SUPBOOK): Supporting workbook'; - $01AF: Result := 'PROT4REV: Shared workbook protection flag'; - $01B0: Result := 'CONDFMT: Conditional formatting range information'; - $01B1: Result := 'CF: Conditional formatting conditions'; - $01B2: Result := 'DVAL: Data validation information'; - $01B5: Result := 'DCONBIN: Data consolidation information'; - $01B6: Result := 'TXO: Text object'; - $01B7: Result := 'REFRESHALL: Refresh flag'; - $01B8: Result := 'HLINK: Hyperlink'; - $01BA: Result := 'CODENAME: Name of the workbook object'; - $01BB: Result := 'SXFDBTYPE: SQL datatype identifier'; - $01BC: Result := 'PROT4REVPASS: Shared workbook protection password'; - $01BE: Result := 'DV: Data validation criteria'; - $01C0: Result := 'EXCEL9FILE: Excel 9 file'; - $01C1: Result := 'RECALCID: Recalc information'; - $0200: Result := 'DIMENSIONS: Cell table size'; - $0201: Result := 'BLANK: Cell Value, blank cell'; - $0203: Result := 'NUMBER: Cell value, floating-point cell'; - $0204: Result := 'LABEL: Cell value, string constant'; - $0205: Result := 'BOOLERR: Cell Value, boolean or error'; - $0206: Result := 'FORMULA: Formula'; - $0207: Result := 'STRING: String value of a formula'; - $0208: Result := 'ROW: Describes a row'; - $0209: Result := 'BOF: Begin of file'; - $020B: Result := 'INDEX: Index record'; - $0218: Result := 'NAME: Defined name'; - $0221: Result := 'ARRAY: Array-entered formula'; - $0223: Result := 'EXTERNNAME: Externally referenced name'; - $0225: Result := 'DEFAULTROWHEIGHT: Default row height'; - $0231: Result := 'FONT: Font description'; - $0236: Result := 'TABLE: Data table'; - $023E: Result := 'WINDOW2: Sheet window information'; - $0243: Result := 'XF: Extended format'; - $027E: Result := 'RK: Cell value, RK number'; - $0293: Result := 'STYLE: Style information'; - $0406: Result := 'FORMULA: Cell formula'; - $0409: Result := 'BOF: Begin of file'; - $041E: Result := 'FORMAT: Number format'; - $0443: Result := 'XF: Extended format'; - $04BC: Result := 'SHAREDFMLA: Shared formula'; - $0800: Result := 'HLINKTOOLTIP: Hyperlink tooltip'; - $0801: Result := 'WEBPUB: Web publish item'; - $0802: Result := 'QSISXTAG: PivotTable and query table extensions'; - $0803: Result := 'DBQUERYEXT: Database query extensions'; - $0804: Result := 'EXTSTRING: FRT string'; - $0805: Result := 'TXTQUERY: Text query information'; - $0806: Result := 'QSIR: Query table formatting'; - $0807: Result := 'QSIF: Query table field formatting'; - $0809: Result := 'BOF: Beginning of file'; - $080A: Result := 'OLEDBCONN: OLE database connection'; - $080B: Result := 'WOPT: Web options'; - $080C: Result := 'SXVIEWEX: Pivot table OLAP extensions'; - $080D: Result := 'SXTH: Pivot table OLAP hierarchy'; - $080E: Result := 'SXPIEX: OLAP page item extensions'; - $080F: Result := 'SXVDTEX: View dimension OLAP extensions'; - $0810: Result := 'SXVIEWX9: Pivot table extensions'; - $0812: Result := 'CONTINUEFRT: Continued FRT'; - $0813: Result := 'REALTIMEDATA: Real-time data (RTD)'; - $0850: Result := 'CHARTFRTINFO: Future record identifiers'; - $0852: Result := 'STARTBLOCK: Beginning of a collection of records'; - $0853: Result := 'ENDBLOCK: End of a collection of records'; - $0862: Result := 'SHEETEXT: Extra sheet info'; - $0863: Result := 'BOOKEXT: Extra book info'; - $0864: Result := 'SXADDL: Pivot table additional info'; - $0865: Result := 'CRASHRECERR: Crash recovery error'; - $0866: Result := 'HFPICTURE: Header/footer picture'; - $0867: Result := 'FEATHEADR: Shared feature header'; - $0868: Result := 'FEAT: Shared feature record'; - $086A: Result := 'DATALABEXT: Chart data label extension'; - $086B: Result := 'DATALABEXTCONTENTS: Chart data label extension contents'; - $086C: Result := 'CELLWATCH: Cell watch'; - $086D: Result := 'FEATINFO: Shared feature info record'; - $0871: Result := 'FEATHEADR11: Shared feature header 11'; - $0872: Result := 'FEAT11: Shared feature 11 record'; - $0873: Result := 'FEATINFO11: Shared feature info 11 record'; - $0874: Result := 'DROPDOWNOBJIDS: Drop down opbject'; - $0875: Result := 'CONTINUEFRT11: Continue FRT 11'; - $0876: Result := 'DCONN: Data connection'; - $0877: Result := 'LIST12: Extra table data introduced in Excel 2007'; - $0878: Result := 'FEAT12: Shared feature 12 record'; - $0879: Result := 'CONDFMT12: Conditional formatting range information 12'; - $087A: Result := 'CF12: Conditional formatting condition 12'; - $087B: Result := 'CFEX: Conditional formatting extension'; - $087C: Result := 'XFCRC: XF extension checksum'; - $087D: Result := 'XFEXT: XF extension'; - $087E: Result := 'EZFILTER12: Autofilter data introduced in Excel 2007'; - $087F: Result := 'CONTINUEFRT12: Continue FRT 12'; - $0881: Result := 'SXADDL12: Additional workbook connections information'; - $0884: Result := 'MDTINFO: Information about a metadata type'; - $0885: Result := 'MDXSTR: MDX metadata string'; - $0886: Result := 'MDXTUPLE: Tuple MDX metadata'; - $0887: Result := 'MDXSET: Set MDX metadata'; - $0888: Result := 'MDXPROP: Member property MDX metadata'; - $0889: Result := 'MDXKPI: Key performance indicator MDX metadata'; - $088A: Result := 'MDTB: Block of metadata records'; - $088B: Result := 'PLV: Page layout view settings in Excel 2007'; - $088C: Result := 'COMPAR12: Compatibility checker 12'; - $088D: Result := 'DXF: Differential XF'; - $088E: Result := 'TABLESTYLES: Table styles'; - $088F: Result := 'TABLESTYLE: Table style'; - $0890: Result := 'TABLESTYLEELEMENT: Table style element'; - $0892: Result := 'STYLEEXT: Named cell style extension'; - $0893: Result := 'NAMEPUBLISH: Publish to Excel server data for name'; - $0894: Result := 'NAMECMT: Name comment'; - $0895: Result := 'SORTDATA12: Sort data 12'; - $0896: Result := 'THEME: Theme'; - $0897: Result := 'GUIDTYPELIB: VB project typelib GUID'; - $0898: Result := 'FNGRP12: Function group'; - $0899: Result := 'NAMEFNGRP12: Extra function group'; - $089A: Result := 'MTRSETTINGS: Multi-threaded calculation settings'; - $089B: Result := 'COMPRESSPICTURES: Automatic picture compression mode'; - $089C: Result := 'HEADERFOOTER: Header footer'; - $089E: Result := 'CRTMLFRT: Additional properties for chart elements'; - $08A3: Result := 'FORCEFULLCALCULATION: Force full calculation settings'; - $08A4: Result := 'SHAPEPROPSSTREAM: Shape formatting properties for chart elements'; - $08A5: Result := 'TEXTPROPSSTREAM: Additional text properties for text in entire chart'; - $08A7: Result := 'CRTLAYOUT12A: Layout information for a plot area'; - $08C1: Result := 'LISTOBJ: List object'; - $08C2: Result := 'LISTFIELD: List field'; - $08C3: Result := 'LISTDV: List data validation'; - $08C4: Result := 'LISTCONDFMT: List conditional formatting'; - $08C5: Result := 'LIST CF: List cell formatting'; - $08C6: Result := 'FMQRY: Filemaker queries'; - $08C7: Result := 'FMSQRY: Filemaker queries'; - $08C8: Result := 'PLV: Page layout view in Mac Excel 11'; - $08C9: Result := 'LNEXT: Extenstion information for borders in Mac Office 11'; - $08CA: Result := 'MKREXT: Extension information for markers in Mac Office 11'; - $08CB: Result := 'CRTCOOPT: Color options for chart series in Mac Office 11'; - $1001: Result := 'UNITS: ignored'; - $1002: Result := 'CHART: Position and size of chart area'; - $1003: Result := 'SERIES: Properties of the data for a series, a trendline, or error bars'; - $1004: Result := 'CHSOURCELINK: Source of data series'; - $1006: Result := 'DATAFORMAT: Formatting properties for data point or series'; - $1007: Result := 'CHLINEFORMAT: Formatting attributes of line or border'; - $1009: Result := 'MARKERFORMAT: Color, size, and shape of data markers'; - $100A: Result := 'AREAFORMAT: Patterns and colors in filled chart region'; - $100B: Result := 'PIEFORMAT: Distance of a data point(s) from pie'; - $100C: Result := 'ATTACHEDLABEL: Properties of series data label'; - $100D: Result := 'CHSTRING: Category name of series, or text for text box in chart'; - $1014: Result := 'CHARTFORMAT: Properties of a chart group'; - $1015: Result := 'LEGEND: Properties of a legend'; - $1016: Result := 'SERIESLIST: Specifies the series for the chart'; - $1017: Result := 'BAR: identifies a bar/column chart group'; - $1018: Result := 'LINE: identifies a line chart group'; - $1019: Result := 'PIE: identifies a pie/doughnut chart group'; - $101A: Result := 'AREA: identifies an area chart group'; - $101B: Result := 'SCATTER: identifies scatter or bubble chart group'; - $101D: Result := 'AXIS: Properties of an axis'; - $101E: Result := 'TICK: Attributes of axis labels and ticks'; - $101F: Result := 'VALUERANGE: Properties of value axis'; - $1021: Result := 'CHAXISLINE: Part of the axis specified by the LINEFORMAT record'; - $1022: Result := 'CRTLINK: not used'; - $1024: Result := 'DEFAULTTEXT: Text elements formatted by TEXT record'; - $1025: Result := 'TEXT: Properties of an attached label'; - $1026: Result := 'FONTX: Font for a given text element'; - $1027: Result := 'OBJECTLINK: specifies object on chart, or entire chart, to which TEXT record is linked.'; - $1032: Result := 'CHFRAME: Border and area formatting of chart'; - $1033: Result := 'CHBEGIN: Indicates begin of a chart record block'; - $1034: Result := 'CHEND: Indicates end of a chart record block'; - $1035: Result := 'PLOTAREA: empty --> see FRAME record specifying plot area properties'; - $103A: Result := 'CHART3D: plot area of the chart group is rendered in a 3-D'; - $103C: Result := 'PICF: Layout of a picture attached to a picture-filled chart elemen'; - $103D: Result := 'DROPBAR: attributes of the up/down bars between multiple series of line chart group'; - $103E: Result := 'RADAR: identifies a radar chart group'; - $103F: Result := 'SURF: identifies a surface chart group'; - $1040: Result := 'RADARAREA: identifies a filled radar chart group'; - $1041: Result := 'AXISPARENT: Properties of an axis group'; - $1043: Result := 'LEGENDEXCEPTION: Information on legend item changed from default'; - $1044: Result := 'SHTPROPS: Chart properties defined by the Chart Sheet Substream ABNF'; - $1045: Result := 'SERTOCRT: Specifies chart group for the current series'; - $1046: Result := 'AXESUSED: Number of axis groups on the chart'; - $1048: Result := 'SBASEREF: Location of a PivotTable view referenced by a chart'; - $104A: Result := 'SERPARENT: Series to which the current trendline or error bar corresponds'; - $104B: Result := 'SERAUXTREND: Specifies a trendline'; - $104E: Result := 'IFMTRECORD: Number format to use for the text on an axis'; - $104F: Result := 'POS: Size/position for legend, attached label, or plot area'; - $1050: Result := 'ALRUNS: Rich Text Formatting within chart titles, trendline, and data labels'; - $1051: Result := 'BRAI: Reference to data used in chart'; - $105B: Result := 'SERAUXERRBAR: Error bar properties'; - $105C: Result := 'CLRTCLIENT: Custom color palette for chart'; - $105D: Result := 'SERFMT: Properties of series data points, markers, or lines'; - $105F: Result := 'CHART3DBARSHAPE: Shape of the data points in bar or column chart group'; - $1060: Result := 'FBI: Scalable font information (chart)'; - $1061: Result := 'BOPPOP: Chart group is a bar or a pie of pie chart'; - $1062: Result := 'AXCEXT: Additional extension properties of a date axis'; - $1063: Result := 'DAT: Chart Sheet Substream ABNF for data table within chart area'; - $1064: Result := 'PLOTGROWTH: Scale factors for font scaling'; - $1065: Result := 'SIINDEX: Specifies data of a chart'; - $1066: Result := 'GELFRAME: Properties of a fill pattern for parts of a chart'; - $1067: Result := 'BOPPOPCUSTOM: Series data points contained in the secondary bar/pie'; - $1068: Result := 'FBI2: Scalable font information (chart)'; - else - Result := '<unknown>'; - end; -end; - -function SheetFuncName(AIndex: Word): String; -begin - case AIndex of - 0 : result := 'COUNT'; - 1 : Result := 'IF'; - 2 : Result := 'ISNA'; - 3 : Result := 'ISERROR'; - 4 : Result := 'SUM'; - 5 : Result := 'AVERAGE'; - 6 : Result := 'MIN'; - 7 : Result := 'MAX'; - 8 : Result := 'ROW'; - 9 : Result := 'COLUMN'; - 10 : Result := 'NA'; - 11 : Result := 'NPV'; - 12 : Result := 'STDEV'; - 13 : Result := 'DOLLAR'; - 14 : Result := 'FIXED'; - 15 : Result := 'SIN'; - 16 : Result := 'COS'; - 17 : Result := 'TAN'; - 18 : Result := 'ATAN'; - 19 : Result := 'PI'; - 20 : Result := 'SQRT'; - 21 : Result := 'EXP'; - 22 : Result := 'LN'; - 23 : Result := 'LOG10'; - 24 : Result := 'ABS'; - 25 : Result := 'INT'; - 26 : Result := 'SIGN'; - 27 : Result := 'ROUND'; - 28 : Result := 'LOOKUP'; - 29 : Result := 'INDEX'; - 30 : Result := 'REPT'; - 31 : Result := 'MID'; - 32 : Result := 'LEN'; - 33 : Result := 'VALUE'; - 34 : Result := 'TRUE'; - 35 : Result := 'FALSE'; - 36 : Result := 'AND'; - 37 : Result := 'OR'; - 38 : Result := 'NOT'; - 39 : Result := 'MOD'; - 40 : Result := 'DCOUNT'; - 41 : Result := 'DSUM'; - 42 : Result := 'DAVERAGE'; - 43 : Result := 'DMIN'; - 44 : Result := 'DMAX'; - 45 : Result := 'DSTDEV'; - 46 : Result := 'VAR'; - 47 : Result := 'DVAR'; - 48 : Result := 'TEXT'; - 49 : Result := 'LINEST'; - 50 : Result := 'TREND'; - 51 : Result := 'LOGEST'; - 52 : Result := 'GROWTH'; - 56 : Result := 'PV'; - 57 : Result := 'FV'; - 58 : Result := 'NPER'; - 59 : Result := 'PMT'; - 60 : Result := 'RATE'; - 61 : Result := 'MIRR'; - 62 : Result := 'IRR'; - 63 : Result := 'RAND'; - 64 : Result := 'MATCH'; - 65 : Result := 'DATE'; - 66 : Result := 'TIME'; - 67 : Result := 'DAY'; - 68 : Result := 'MONTH'; - 69 : Result := 'YEAR'; - 70 : Result := 'WEEKDAY'; - 71 : Result := 'HOUR'; - 72 : Result := 'MINUTE'; - 73 : Result := 'SECOND'; - 74 : Result := 'NOW'; - 75 : Result := 'AREAS'; - 76 : Result := 'ROWS'; - 77 : Result := 'COLUMNS'; - 78 : Result := 'OFFSET'; - 82 : Result := 'SEARCH'; - 83 : Result := 'TRANSPOSE'; - 86 : Result := 'TYPE'; - 97 : Result := 'ATAN2'; - 98 : Result := 'ASIN'; - 99 : Result := 'ACOS'; - 100 : Result := 'CHOOSE'; - 101 : Result := 'HLOOKUP'; - 102 : Result := 'VLOOKUP'; - 105 : Result := 'ISREF'; - 109 : Result := 'LOG'; - 111 : Result := 'CHAR'; - 112 : Result := 'LOWER'; - 113 : Result := 'UPPER'; - 114 : Result := 'PROPER'; - 115 : Result := 'LEFT'; - 116 : Result := 'RIGHT'; - 117 : Result := 'EXACT'; - 118 : Result := 'TRIM'; - 119 : Result := 'REPLACE'; - 120 : Result := 'SUBSTITUTE'; - 121 : Result := 'CODE'; - 124 : Result := 'FIND'; - 125 : Result := 'CELL'; - 126 : Result := 'ISERR'; - 127 : Result := 'ISTEXT'; - 128 : Result := 'ISNUMBER'; - 129 : Result := 'ISBLANK'; - 130 : Result := 'T'; - 131 : Result := 'N'; - 140 : Result := 'DATEVALUE'; - 141 : Result := 'TIMEVALUE'; - 142 : Result := 'SLN'; - 143 : Result := 'SYD'; - 144 : Result := 'DDB'; - 148 : Result := 'INDIRECT'; - 162 : Result := 'CLEAN'; - 163 : Result := 'MDETERM'; - 164 : Result := 'MINVERSE'; - 165 : Result := 'MMULT'; - 167 : Result := 'IPMT'; - 168 : Result := 'PPMT'; - 169 : Result := 'COUNTA'; - 183 : Result := 'PRODUCT'; - 184 : Result := 'FACT'; - 189 : Result := 'DPRODUCT'; - 190 : Result := 'ISNONTEXT'; - 193 : Result := 'STDEVP'; - 194 : Result := 'VARP'; - 195 : Result := 'DSTDEVP'; - 196 : Result := 'DVARP'; - 197 : Result := 'TRUNC'; - 198 : Result := 'ISLOGICAL'; - 199 : Result := 'DCOUNTA'; - 204 : Result := 'YEN/USDOLLAR'; - 205 : Result := 'FINDB'; - 206 : Result := 'SEARCHB'; - 207 : Result := 'REPLACEB'; - 208 : Result := 'LEFTB'; - 209 : Result := 'RIGHTB'; - 210 : Result := 'MIDB'; - 211 : Result := 'LENB'; - 212 : Result := 'ROUNDUP'; - 213 : Result := 'ROUNDDOWN'; - 214 : Result := 'ASC'; - 215 : Result := 'JIS / DBCS'; - 216 : Result := 'RANK'; - 219 : Result := 'ADDRESS'; - 220 : Result := 'DAYS360'; - 221 : Result := 'TODAY'; - 222 : Result := 'VDB'; - 227 : Result := 'MEDIAN'; - 228 : Result := 'SUMPRODUCT'; - 229 : Result := 'SINH'; - 230 : Result := 'COSH'; - 231 : Result := 'TANH'; - 232 : Result := 'ASINH'; - 233 : Result := 'ACOSH'; - 234 : Result := 'ATANH'; - 235 : Result := 'DGET'; - 244 : Result := 'INFO'; - 247 : Result := 'DB'; - 252 : Result := 'FREQUENCY'; - 261 : Result := 'ERROR.TYPE'; - 269 : Result := 'AVEDEV'; - 270 : Result := 'BETADIST'; - 271 : Result := 'GAMMALN'; - 272 : Result := 'BETAINV'; - 273 : Result := 'BINOMDIST'; - 274 : Result := 'CHIDIST'; - 275 : Result := 'CHIINV'; - 276 : Result := 'COMBIN'; - 277 : Result := 'CONFIDENCE'; - 278 : Result := 'CRITBINOM'; - 279 : Result := 'EVEN'; - 280 : Result := 'EXPONDIST'; - 281 : Result := 'FDIST'; - 282 : Result := 'FINV'; - 283 : Result := 'FISHER'; - 284 : Result := 'FISHERINV'; - 285 : Result := 'FLOOR'; - 286 : Result := 'GAMMADIST'; - 287 : Result := 'GAMMAINV'; - 288 : Result := 'CEILING'; - 289 : Result := 'HYPGEOMDIST'; - 290 : Result := 'LOGNORMDIST'; - 291 : Result := 'LOGINV'; - 292 : Result := 'NEGBINOMDIST'; - 293 : Result := 'NORMDIST'; - 294 : Result := 'NORMSDIST'; - 295 : Result := 'NORMINV'; - 296 : Result := 'NORMSINV'; - 297 : Result := 'STANDARDIZE'; - 298 : Result := 'ODD'; - 299 : Result := 'PERMUT'; - 300 : Result := 'POISSON'; - 301 : Result := 'TDIST'; - 302 : Result := 'WEIBULL'; - 303 : Result := 'SUMXMY2'; - 304 : Result := 'SUMX2MY2'; - 305 : Result := 'SUMX2PY2'; - 306 : Result := 'CHITEST'; - 307 : Result := 'CORREL'; - 308 : Result := 'COVAR'; - 309 : Result := 'FORECAST'; - 310 : Result := 'FTEST'; - 311 : Result := 'INTERCEPT'; - 312 : Result := 'PEARSON'; - 313 : Result := 'RSQ'; - 314 : Result := 'STEYX'; - 315 : Result := 'SLOPE'; - 316 : Result := 'TTEST'; - 317 : Result := 'PROB'; - 318 : Result := 'DEVSQ'; - 319 : Result := 'GEOMEAN'; - 320 : Result := 'HARMEAN'; - 321 : Result := 'SUMSQ'; - 322 : Result := 'KURT'; - 323 : Result := 'SKEW'; - 324 : Result := 'ZTEST'; - 325 : Result := 'LARGE'; - 326 : Result := 'SMALL'; - 327 : Result := 'QUARTILE'; - 328 : Result := 'PERCENTILE'; - 329 : Result := 'PERCENTRANK'; - 330 : Result := 'MODE'; - 331 : Result := 'TRIMMEAN'; - 332 : Result := 'TINV'; - 336 : Result := 'CONCATENATE'; - 337 : Result := 'POWER'; - 342 : Result := 'RADIANS'; - 343 : Result := 'DEGREES'; - 344 : Result := 'SUBTOTAL'; - 345 : Result := 'SUMIF'; - 346 : Result := 'COUNTIF'; - 347 : Result := 'COUNTBLANK'; - 350 : Result := 'ISPMT'; - 351 : Result := 'DATEDIF'; - 352 : Result := 'DATESTRING'; - 353 : Result := 'NUMBERSTRING'; - 354 : Result := 'ROMAN'; - 358 : Result := 'GETPIVOTDATA'; - 359 : Result := 'HYPERLINK'; - 360 : Result := 'PHONETIC'; - 361 : Result := 'AVERAGEA'; - 362 : Result := 'MAXA'; - 363 : Result := 'MINA'; - 364 : Result := 'STDEVPA'; - 365 : Result := 'VARPA'; - 366 : Result := 'STDEVA'; - 367 : Result := 'VARA'; - else Result := 'unknown'; - end; -end; - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/behtml.pas b/components/fpspreadsheet/reference/BIFFExplorer/behtml.pas deleted file mode 100644 index 71f255619..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/behtml.pas +++ /dev/null @@ -1,245 +0,0 @@ -unit beHTML; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, Graphics; - -type - THTMLHeader = (h1, h2, h3, h4, h5); - THeaderColors = Array[THTMLHeader] of TColor; - - THTMLDocument = class - private - FLines: TStrings; - FRawMode: Boolean; - FIndent: Integer; - function Indent: String; - function Raw(const AText: String): String; - function ColorToHTML(AColor: TColor): String; - public - constructor Create; - destructor Destroy; override; - procedure AddEmptyLine; - procedure AddListItem(const AText: String); - procedure AddHeader(AHeader: THTMLHeader; const AText: String); - procedure AddParagraph(const AText: String); - procedure BeginDocument(const ATitle: String; const AHeaderColors: THeaderColors; - ARawMode: Boolean=false); - procedure BeginBulletList; - procedure BeginNumberedList; - function Bold(const AText: String): String; - procedure EndDocument; - procedure EndBulletList; - procedure EndNumberedList; - function Hyperlink(const AText, ALink: String): String; - function Italic(const AText: String): String; - property Lines: TStrings read FLines; - end; - -implementation - -uses - StrUtils, LCLIntf; - -constructor THTMLDocument.Create; -begin - inherited; - FLines := TStringList.Create; -end; - -destructor THTMLDocument.Destroy; -begin - FLines.Free; - inherited; -end; - -procedure THTMLDocument.AddHeader(AHeader: THTMLHeader; const AText: String); -begin - if FRawMode then - FLines.Add(Raw(AText)) - else - FLines.Add(Format('%s<h%d>%s</h%d>', [Indent, ord(AHeader)+1, AText, ord(AHeader)+1])); -end; - - (* - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> -<!-- HTML Codes by Quackit.com --> -<title> -Title appears in the browser's title bar... - - - - - -

Heading goes here...

-

Enter your paragraph text here...

- - - *) - -procedure THTMLDocument.BeginDocument(const ATitle: String; - const AHeaderColors: THeaderColors; ARawMode: Boolean = false); -begin - FRawMode := ARawMode; - FLines.Clear; - if not FRawMode then begin - FLines.Add(''); - FLines.Add(''); - FLines.Add(' '); - FLines.Add(' '); - FLines.Add(' ' + ATitle + ''); - FLines.Add(' '); - FLines.Add(' '); - FLines.Add(' '); - FIndent := 4; - end; -end; - -procedure THTMLDocument.BeginBulletList; -begin - if not FRawMode then begin - FLines.Add(Indent + '
    '); - inc(FIndent, 2); - end; -end; - -procedure THTMLDocument.BeginNumberedList; -begin - if not FRawMode then begin - FLines.Add(Indent + '
      '); - inc(FIndent, 2); - end; -end; - -procedure THTMLDocument.AddEmptyLine; -begin - if FRawMode then - FLines.Add('') - else - FLines.Add('
      '); -end; - -procedure THTMLDocument.AddListItem(const AText: String); -begin - if FRawMode then - FLines.Add('- ' + Raw(AText)) - else - FLines.Add(Indent + '
    1. ' + AText + '
    2. '); -end; - -procedure THTMLDocument.AddParagraph(const AText: String); -begin - if FRawMode then - FLines.Add(Raw(AText)) - else - FLines.Add(Indent + '

      ' + AText + '

      '); -end; - -function THTMLDocument.Bold(const AText: String): String; -begin - if FRawMode then - Result := AText - else - Result := '' + AText + ''; -end; - -function THTMLDocument.ColorToHTML(AColor: TColor): String; -var - tmpRGB: LongInt; -begin - tmpRGB := ColorToRGB(AColor) ; - Result := Format('#%.2x%.2x%.2x', [ - GetRValue(tmpRGB), - GetGValue(tmpRGB), - GetBValue(tmpRGB) - ]) ; -end; - -procedure THTMLDocument.EndDocument; -begin - if not FRawMode then begin - FLines.Add(' '); - FLines.Add(''); - end; -end; - -procedure THTMLDocument.EndBulletList; -begin - if not FRawMode then begin - dec(FIndent, 2); - FLines.Add(Indent + '
'); - end; -end; - -procedure THTMLDocument.EndNumberedList; -begin - if not FRawMode then begin - dec(FIndent, 2); - FLines.Add(Indent + ''); - end; -end; - -function THTMLDocument.Hyperlink(const AText, ALink: String): String; -begin - if FRawMode then - Result := Format('%s (%s)', [AText, ALink]) - else - Result := Format('%s', [ALink, AText]); -end; - -function THTMLDocument.Indent: String; -begin - Result := DupeString(' ', FIndent); -end; - -function THTMLDocument.Italic(const AText: String): String; -begin - if FRawMode then - Result := AText - else - Result := '' + AText + ''; -end; - -function THTMLDocument.Raw(const AText: String): String; -var - i, n: Integer; -begin - Result := ''; - if AText = '' then - exit; - n := Length(AText); - i := 1; - while (i <= n) do begin - if AText[i] = '<' then - repeat - inc(i); - until (i = n) or (AText[i] = '>') - else - Result := Result + AText[i]; - inc(i); - end; -end; - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/bemain.lfm b/components/fpspreadsheet/reference/BIFFExplorer/bemain.lfm deleted file mode 100644 index 0b4b9dd21..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/bemain.lfm +++ /dev/null @@ -1,1061 +0,0 @@ -object MainForm: TMainForm - Left = 352 - Height = 576 - Top = 177 - Width = 1089 - AllowDropFiles = True - Caption = 'BIFF Explorer' - ClientHeight = 556 - ClientWidth = 1089 - Menu = MainMenu - OnCloseQuery = FormCloseQuery - OnCreate = FormCreate - OnDestroy = FormDestroy - OnDropFiles = FormDropFiles - OnShow = FormShow - ShowHint = True - LCLVersion = '1.7' - object Splitter1: TSplitter - Left = 419 - Height = 508 - Top = 25 - Width = 5 - end - object ToolBar: TToolBar - Left = 4 - Height = 25 - Top = 0 - Width = 1085 - AutoSize = True - BorderSpacing.Left = 4 - ButtonHeight = 25 - Caption = 'ToolBar' - EdgeBorders = [] - Images = ImageList - TabOrder = 1 - object ToolButton1: TToolButton - Left = 1 - Top = 0 - Action = AcFileOpen - DropdownMenu = RecentFilesPopupMenu - Style = tbsDropDown - end - object ToolButton2: TToolButton - Left = 64 - Top = 0 - Action = AcFileQuit - end - object ToolButton3: TToolButton - Left = 36 - Top = 0 - Action = AcFind - end - object ToolButton4: TToolButton - Left = 59 - Height = 25 - Top = 0 - Width = 5 - Caption = 'ToolButton4' - Style = tbsDivider - end - end - object DetailPanel: TPanel - Left = 424 - Height = 508 - Top = 25 - Width = 665 - Align = alClient - BevelOuter = bvNone - ClientHeight = 508 - ClientWidth = 665 - TabOrder = 3 - object PageControl: TPageControl - Left = 0 - Height = 508 - Top = 0 - Width = 665 - ActivePage = PgValues - Align = alClient - TabIndex = 1 - TabOrder = 0 - OnChange = PageControlChange - object PgAnalysis: TTabSheet - Caption = 'Analysis' - ClientHeight = 480 - ClientWidth = 657 - object AnalysisDetails: TMemo - Left = 0 - Height = 191 - Top = 289 - Width = 657 - Align = alBottom - Font.CharSet = ANSI_CHARSET - Font.Height = -12 - Font.Name = 'Courier New' - Font.Pitch = fpFixed - Font.Quality = fqDraft - ParentFont = False - ScrollBars = ssAutoBoth - TabOrder = 0 - WordWrap = False - end - object DetailsSplitter: TSplitter - Cursor = crVSplit - Left = 0 - Height = 5 - Top = 284 - Width = 657 - Align = alBottom - ResizeAnchor = akBottom - end - end - object PgValues: TTabSheet - Caption = 'Values' - ClientHeight = 480 - ClientWidth = 657 - object ValueGrid: TStringGrid - Left = 0 - Height = 158 - Top = 322 - Width = 657 - Align = alBottom - ColCount = 3 - DefaultColWidth = 100 - FixedCols = 0 - MouseWheelOption = mwGrid - Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goColSizing, goThumbTracking, goSmoothScroll] - RowCount = 9 - TabOrder = 3 - TitleStyle = tsNative - OnClick = ValueGridClick - OnPrepareCanvas = ValueGridPrepareCanvas - ColWidths = ( - 112 - 142 - 141 - ) - Cells = ( - 3 - 0 - 0 - 'Data type' - 1 - 0 - 'Value' - 2 - 0 - 'Offset range' - ) - end - object HexSplitter: TSplitter - Cursor = crVSplit - Left = 0 - Height = 5 - Top = 317 - Width = 657 - Align = alBottom - ResizeAnchor = akBottom - 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 - object TreePanel: TPanel - Left = 0 - Height = 508 - Top = 25 - Width = 419 - Align = alLeft - BevelOuter = bvNone - ClientHeight = 508 - ClientWidth = 419 - Constraints.MinWidth = 275 - TabOrder = 2 - object FindPanel: TPanel - Left = 0 - Height = 30 - Top = 478 - Width = 419 - Align = alBottom - BevelOuter = bvNone - ClientHeight = 30 - ClientWidth = 419 - TabOrder = 1 - Visible = False - object BtnFindNext: TSpeedButton - Left = 240 - Height = 22 - Top = 3 - Width = 23 - Action = AcFindNext - Flat = True - end - object BtnFindPrev: TSpeedButton - Left = 216 - Height = 22 - Top = 3 - Width = 23 - Action = AcFindPrev - Flat = True - end - object SpeedButton3: TSpeedButton - Left = 3 - Height = 22 - Top = 3 - Width = 23 - Action = AcFindClose - Flat = True - end - object CbFind: TComboBox - Left = 28 - Height = 23 - Top = 3 - Width = 183 - ItemHeight = 15 - OnChange = CbFindChange - OnKeyPress = CbFindKeyPress - TabOrder = 0 - end - end - object BIFFTree: TVirtualStringTree - Left = 0 - Height = 478 - Top = 0 - Width = 419 - Align = alClient - ButtonStyle = bsTriangle - DefaultText = 'Node' - Header.AutoSizeIndex = 4 - Header.Columns = < - item - Alignment = taRightJustify - CaptionAlignment = taRightJustify - MinWidth = 80 - Options = [coAllowClick, coDraggable, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus, coUseCaptionAlignment] - Position = 0 - Text = 'Offset' - Width = 80 - end - item - Alignment = taCenter - MinWidth = 60 - Position = 1 - Text = 'Record ID' - Width = 80 - end - item - MinWidth = 80 - Position = 2 - Text = 'Record name' - Width = 130 - end - item - Alignment = taCenter - MinWidth = 50 - Position = 3 - Text = 'Index' - end - item - MinWidth = 80 - Position = 4 - Text = 'Record description' - Width = 80 - end> - Header.DefaultHeight = 24 - Header.Font.Style = [fsBold] - Header.Height = 24 - Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible] - HintMode = hmTooltip - PopupMenu = TreePopupMenu - TabOrder = 0 - TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoSpanColumns, toAutoTristateTracking, toAutoDeleteMovedNodes] - TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowRoot, toThemeAware, toUseBlendedImages] - TreeOptions.SelectionOptions = [toFullRowSelect] - OnBeforeCellPaint = BIFFTreeBeforeCellPaint - OnFocusChanged = BIFFTreeFocusChanged - OnFreeNode = BIFFTreeFreeNode - OnGetText = BIFFTreeGetText - OnPaintText = BIFFTreePaintText - OnGetNodeDataSize = BIFFTreeGetNodeDataSize - end - end - object StatusBar: TStatusBar - Left = 0 - Height = 23 - Top = 533 - Width = 1089 - Panels = < - item - Width = 120 - end - item - Width = 180 - end - item - Width = 150 - end - item - Width = 180 - end> - SimplePanel = False - end - object ImageList: TImageList - left = 80 - top = 64 - Bitmap = { - 4C69090000001000000010000000FFFFFF00FFFFFF000088CC610088CC810088 - CC810088CC810088CC810088CC810088CC810088CC810088CC810088CC810088 - CC810088CC610087CB00FFFFFF00FFFFFF00FFFFFF000087CA8388DCF4FF60C0 - E9FF5FBFEAFF80D3F4FF9CE3FDFFA2E6FFFFA2E6FFFFA2E6FFFFA2E6FFFFA6EA - FFFF0087CA830087CA00FFFFFF00FFFFFF00FFFFFF000085C885ACF1FFFFABEF - FEFF95E2F8FF6EC9EDFF48A8D9FF98DCFEFF98DCFEFF98DCFEFF98DCFEFFA1E5 - FFFF0085C8850085C800FFFFFF00FFFFFF00FFFFFF000084C587A9EEFDFFA4E9 - FCFFA4E9FCFFAAEEFDFF42A1D1FF97DBFDFF97DBFDFF97DBFDFF97DBFDFF9FE3 - FEFF0084C5870084C500FFFFFF00FFFFFF00FFFFFF000082C28AA6EBFCFFA1E6 - FBFFA1E6FBFFA6EBFCFF3C9DCFFF96DAFCFF96DAFCFF96DAFCFF96DAFCFF9EE2 - FDFF0082C28A0082C200FFFFFF00FFFFFF00FFFFFF00007FBF8DA3E8FBFF9DE3 - F9FF9DE3F9FFA3E8FBFF3594C5FF94D8FAFF94D8FAFF94D8FAFF94D8FAFF9BDF - FCFF007FBF8D007FBE00FFFFFF00FFFFFF00FFFFFF00007DBB909EE5F9FF98DF - F6FF98DFF6FF9EE5F9FF3290C0FF92D6F8FF92D6F8FF92D6F8FF92D6F8FF99DD - FAFF007DBB90007DBB33FFFFFF00FFFFFF00FFFFFF00007BB8949BE1F7FF94DB - F4FF94DBF4FF9BE1F7FF308DBCFF90D4F6FF90D4F6FF90D4F6FF90D4F6FF97DB - F9FFFEFEFDFF007BB894FFFFFF00FFFFFF00FFFFFF000078B49797DEF6FF90D8 - F2FF90D8F2FF97DEF6FF2D89B7FF8FD3F5FF8FD3F5FF8FD3F5FF8FD3F5FF95D9 - F8FFF5F5EEFF0078B497FFFFFF00FFFFFF00FFFFFF000076B09B92DAF4FF8BD4 - F0FF8BD4F0FF92DAF4FF2B85B3FF8DD1F3FF8DD1F3FF8DD1F3FF8DD1F3FF93D7 - F6FFEBEBDDFF0076B09BFFFFFF00FFFFFF00FFFFFF000073AC9E8ED6F2FF87D0 - EDFF87D0EDFF8ED6F2FF2882AFFF8BCFF1FF8BCFF1FF8BCFF1FF8BCFF1FF91D5 - F5FFFEC941FF0073AC9EFFFFFF00FFFFFF00FFFFFF00006FA7A48AD3F0FF82CD - EBFF82CDEBFF8AD3F0FF267EABFF8ACEF0FF8ACEF0FF8ACEF0FF8ACEF0FF8FD3 - F4FFF4B62EFF006FA7A4FFFFFF00FFFFFF00FFFFFF00006699B287D1EFFF7FCA - E9FF7FCAE9FF87D0EFFF267DA9FF8DD1F3FF8DD1F3FF8DD1F3FF8DD1F3FF90D4 - F5FF006699B200679B3EFFFFFF00FFFFFF00FFFFFF00005E8D8E3591BDF169B8 - DDFA81CBECFF84CEEEFF005C8BEF005D8CBE005D8CBE005D8CBE005D8CBE005D - 8CBE005E8D8E00669900FFFFFF00FFFFFF00FFFFFF00005D8C00006599500064 - 97991C7AA9C052A5CDE0005B89C1005B8900005B8900005B8900005B8900005B - 8900005D8C0000669900FFFFFF00FFFFFF00FFFFFF00005D8C00006497000062 - 9300005E8E30005C8C7C0059879200598700005B8900005B8900005B8900005B - 8900005D8C0000669900FFFFFF00003F9300003F9300003F9300003F9424003F - 948A003E93CC004095CC004095CC004095CC004095CC004095CC004095CC0040 - 95CC004095CC00409599FFFFFF00003F9300003F9324003F938A0E4B9CD33F76 - C0EC5D90D4FF3365A9FFA0A0A0FFA9A9A9FFA9A9A9FFAAAAAAFFACACACFFAEAE - AEFFB0B0B0FF003E93CCFFFFFF00003F938A0E4A9CD33E75BFEC5487CBFF3669 - ADFF23569AFF3363A6FFA9A9A9FFBCBCBCFFBDBDBDFFBFBFBFFFC1C1C1FFC4C4 - C4FFC7C7C7FF003C90CCFFFFFF00003D91CC5D90D4FF3568ACFF285B9FFF1A4D - 91FF4477BBFF3361A4FFA9A9A9FFBDBDBDFFBFBFBFFFC1C1C1FFC4C4C4FFC7C7 - C7FFC9C9C9FF003A8DCCFFFFFF00003B8ECC588BCFFF1A4D91FF4376BAFF3265 - A9FF4376BAFF335FA1FFAAAAAAFFBFBFBFFFC1C1C1FFC4C4C4FFC7C7C7FFC9C9 - C9FFCCCCCCFF003789CCFFFFFF0000398BCC5588CCFF275A9EFF4174B8FF3164 - A8FF4174B8FF335D9EFFACACACFFC1C1C1FFC4C4C4FFC7C7C7FFC9C9C9FFCCCC - CCFFD0D0D0FF003485CCFFFFFF00003688CC5386CAFF295CA0FF3F72B6FF3063 - A7FF3F72B6FF335A9AFFAEAEAEFFC4C4C4FFC7C7C7FFC9C9C9FFCCCCCCFFD0D0 - D0FFD3D3D3FF003181CCFFFFFF00003485CC5083C7FF1D5094FF3265A9FF2D60 - A4FF3D70B4FF335897FFB0B0B0FFC7C7C7FFC9C9C9FFCCCCCCFFD0D0D0FFD3D3 - D3FFD5D5D5FF002E7DCCFFFFFF00003181CC4C7FC3FFBBBBBBFF22518CFF2C5F - A3FF3B6EB2FF335593FFB3B3B3FFC9C9C9FFCCCCCCFFD0D0D0FFD3D3D3FFD5D5 - D5FFD8D8D8FF002B78CCFFFFFF00002E7DCC497CC0FF09336FFF215090FF2B5E - A2FF396CB0FF335290FFB5B5B5FFCCCCCCFFD0D0D0FFD3D3D3FFD5D5D5FFD8D8 - D8FFDBDBDBFF002774CCFFFFFF00002B79CC477ABEFF2C5FA3FF376AAEFF2B5E - A2FF376AAEFF33508CFFB8B8B8FFD0D0D0FFD3D3D3FFD5D5D5FFD8D8D8FFDBDB - DBFFDCDCDCFF00246FCCFFFFFF00002875CC4477BBFF2C5FA3FF3568ACFF2B5E - A2FF2E61A5FF334B87FFBBBBBBFFD3D3D3FFD5D5D5FFD8D8D8FFDBDBDBFFDCDC - DCFFDDDDDDFF001F68CCFFFFFF00002571CC4174B8FF2C5FA3FF2D60A4FF2356 - 9AFF3D70B4FF334179FFBEBEBEFFD5D5D5FFD8D8D8FFDBDBDBFFDCDCDCFFDDDD - DDFFDDDDDDFF001258CCFFFFFF0000226DCC3F72B6FF225599FF3B6EB2FF2C51 - 96EC0A1C60D3000749A4000648CC000648CC000648CC000648CC000648CC0006 - 48CC000648CC00074A99FFFFFF00001B64CC4174B8FF2A5094EC0A1A5ED30008 - 4A8A000648240006470000044500000445000004450000044500000445000004 - 45000004450000064800FFFFFF0000105500000B4FCC0007498A000546240005 - 4700000648000006470000044500000445000004450000044500000445000004 - 45000004450000064800FFFFFF004E4E4E005151510054545411555555405555 - 555A555555655555555A5555554054545411515151004E4E4E004E4E4E002957 - 27000569000007710000FFFFFF004E4E4E005151512163605E62B1A3948BE6D5 - C5AFF4EADFC7EDE3D9B5B6ACA28E63605E62515151214E4E4E004E4E4E004E4E - 4E004E4E4E004E4E4E00FFFFFF004D4D4D115F5D5A64D5C1AEA1EBD8C4C2F6EC - E2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D5B644D4D4D114C4C4C004C4C - 4C004C4C4C004C4C4C00FFFFFF0049494943AD9F918EE8D2BBC0F1E3D5C8F6ED - E4CEF6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4979149494943494949004949 - 49004949490049494900FFFFFF0043434360E0CBB6ACE8D2BBC0E8D2BBC0E8D2 - BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E4D3C1B243434360434343004343 - 43004343430043434300FFFFFF003E3E3E6FE9D4BEBEE8D2BBC0E8D2BBC0F6ED - E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEEDDBC8C53E3E3E6F3E3E3E003E3E - 3E003E3E3E003E3E3E00FFFFFF0038383865E1CFBCB1E8D2BBC0F6EDE4CEF6ED - E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEE7D8CAB838383865383838003838 - 38003838380038383800FFFFFF0031313149A89D9397EAD5BFC3F5E9DFCBF6ED - E4CEF6EDE4CEF6EDE4CEF6EDE4CEF6ECE2CEADA69E9D31313149313131003131 - 31003131310031313100FFFFFF00262626143B3A3874D7C9BCAFF3E6D9CBF6ED - E4CEF6EDE4CEF6EDE4CEF7EFE6D1E4DED9C84544437D34343424383838003939 - 39003A3A3A003C3C3C00FFFFFF001E1E1E001111112A2826257D9D9791A5EEE8 - E3C4F9F3EDD6EFEAE5C5A3A09EA92827278AACACACFF373737753737371F3939 - 39003A3A3A003C3C3C00FFFFFF001E1E1E000E0E0E0004040416040404560404 - 04790404048704040479040404560404042A0F0F0F86B8B5B5FF4241417E3838 - 382A3A3A3A003C3C3C00FFFFFF001E1E1E000E0E0E0004040400040404000404 - 040004040400040404000404040004040400040404251A1A1A8FC8C1C1FF4F4D - 4D88393939383C3C3C00FFFFFF001E1E1E000E0E0E0004040400040404000404 - 040004040400040404000404040004040400040404000404043328272799D9CE - CEFF605C5C913A3A3A4DFFFFFF001E1E1E000E0E0E0004040400040404000404 - 0400040404000404040004040400040404000404040004040400040404443B38 - 38A2E8D8D8FF32323276FFFFFF001E1E1E000E0E0E0004040400040404000404 - 0400040404000404040004040400040404000404040004040400040404000404 - 045C090909892525252CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A7000000AA480000 - AACC0000AA480000A7000000A3000000A3000000A7000000AA480000AACC0000 - AA480000A700FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A7480000A7CC7777 - FFFF0000A7CC0000A7480000A3000000A3000000A7480000A7CC7070F8FF0000 - A7CC0000A748FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A3CC7676FEFF4C4C - D4FF7272FAFF0000A3CC0000A3480000A3480000A3CC6262EAFF4C4CD4FF5C5C - E4FF0000A3CCFFFFFF00FFFFFF00FFFFFF00FFFFFF000000A1480000A0CC6767 - EFFF3636BEFF5E5EE6FF0000A0CC0000A0CC4F4FD7FF3636BEFF4545CDFF0000 - A0CC0000A148FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A00000009C480000 - 9BCC5353DBFF2E2EB7FF3D3DC6FF3131BAFF15159FFF1E1EA8FF00009BCC0000 - 9C480000A000FFFFFF00FFFFFF00FFFFFF00FFFFFF000000A00000009B000000 - 9848000097CC2525B4FF1111A2FF1111A2FF1414A5FF000097CC000098480000 - 9B000000A000FFFFFF00FFFFFF00FFFFFF00FFFFFF000000870000008D000000 - 9148000092CC1515AFFF1111ACFF1111ACFF1111ACFF000092CC000091480000 - 8D0000008700FFFFFF00FFFFFF00FFFFFF00FFFFFF000000870000008C480000 - 8DCC1111B8FF1111B8FF1111B8FF1111B8FF1111B8FF1111B8FF00008DCC0000 - 8C4800008700FFFFFF00FFFFFF00FFFFFF00FFFFFF0000008748000087CC1111 - C4FF1111C4FF1111C4FF000087CC000087CC1111C4FF1111C4FF1111C4FF0000 - 87CC00008748FFFFFF00FFFFFF00FFFFFF00FFFFFF00000082CC1111D0FF1111 - D0FF1111D0FF000082CC0000834800008348000082CC1111D0FF1111D0FF1111 - D0FF000082CCFFFFFF00FFFFFF00FFFFFF00FFFFFF0000007548000072CC1111 - D8FF000072CC00007548000082000000820000007548000072CC1111D8FF0000 - 72CC00007548FFFFFF00FFFFFF00FFFFFF00FFFFFF0000007200000061480000 - 5FCC00006148000072000000820000008200000072000000614800005FCC0000 - 614800007200FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00E69B3D33E89D3FCCE89D3FCCE89D - 3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D3FCCE89D - 3FCCE89D3FCCE69B3D33FFFFFF00FFFFFF00E2973A15DF9438AEF0BD69E6FEDE - 92FFFCD68AFFFCD68AFFFCD68AFFFCD68AFFFCD589FFFCD589FFFDDA8EFFEFBA - 66E6DF9438AEE2973A15FFFFFF00FFFFFF00E2973A00D98E3315D2872EAEE8B5 - 63E6F7CB7FFFEAAF63FFE0A559FFD69B4FFFD19549FFDDAC60FFDFA553E6D287 - 2EAED98E3315E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802915C379 - 23AEDCA553E6E3B25DFFD3953BFFD3953BFFDFA952FFD69A45E6C37923AECB80 - 2915D98E3300E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802900BC71 - 1D15B56A18AED69737E6F1B436FFF0B130FFD4922DE6B56A18AEBC711D15CB80 - 2900D98E3300E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802900BC71 - 1D00AE631215A75C0DAED38D19E6D38C18E6A75C0DAEAE631215BC711D00CB80 - 2900D98E3300E2973A00FFFFFF00FFFFFF00E2973A00D98E3300CB802900BC71 - 1D00AE631200A05509159B5005AE9B5005AEA0550915AE631200BC711D00CB80 - 2900D98E3300E2973A00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C3792300D287 - 2E00DF943800E79C3E5CE89D3FCCE79C3E5CDF943800D2872E00C3792300B56A - 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C3792300D287 - 2E00DE93375CDF9438CCFFE599FFDF9438CCDE93375CD2872E00C3792300B56A - 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C3792300D085 - 2D5CD2872ECCFEE195FFF8C77BFFFDDE92FFD2872ECCD0852D5CC3792300B56A - 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B56A1800C177225CC379 - 23CCFBD98DFFECB367FFE1A75BFFD79C50FFE7BC70FFC37923CCC177225CB56A - 1800A75C0D00FFFFFF00FFFFFF00FFFFFF00A75C0D00B368175CB56A18CCF8CF - 80FFE6A53EFFDE9D2FFFDD9C2EFFDD9C2EFFDD9C2EFFE6AE47FFB56A18CCB368 - 175CA75C0D00FFFFFF00FFFFFF00FFFFFF00A55A0C5CA75C0DCCF9C966FFFAB8 - 27FFFBB71CFFFBB518FFFBB414FFFBB311FFFBB20FFFFBB20EFFFBB516FFA75C - 0DCCA55A0C5CFFFFFF00FFFFFF00FFFFFF009C5106999B5005CC9B5005CC9B50 - 05CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B5005CC9B50 - 05CC9C510699FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF004F4F4F005050500052525200535353005454 - 54155555553E555555555555556355555563555555555555553E545454155353 - 530052525200505050004F4F4F004F4F4F0050505000525252075353533D7373 - 7378C8C8C8D2EAEAEAFFE6E6E6FFE6E6E6FFEAEAEAFFC7C7C7D2727272785353 - 533D52525207505050004F4F4F004F4F4F00505050075151514D9F9F9FA1E6E6 - E6FFD7B0A3FFD08C75FFCD6C4BFFCD6C4BFFD08C75FFD6AFA2FFE3E4E4FF9D9D - 9DA15151514D505050074F4F4F004E4E4E004E4E4E3F9D9D9DA2DFDFDFFFCB79 - 5EFFDB7A58FFEE906EFFF49674FFF49573FFED8E6CFFDA7856FFCB795EFFDBDC - DCFF999999A24E4E4E3F4E4E4E004B4B4B176C6C6C7CDFE0E0FFC8755AFFE283 - 61FFDC7A58FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2987FFFDF7E5CFFC875 - 5AFFD8D8D8FF6969697C4B4B4B1748484842BEBFBFD4C9A295FFD57452FFE281 - 5FFFD26C4AFFD5A291FFD5A291FFE6C2B6FFFFFFFFFFE0AD9CFFDF7C5AFFD16E - 4CFFC7A194FFB2B3B3D4484848424545455CDBDCDCFFC07C65FFDF805EFFCF69 - 47FFCF6947FFCA6442FFC05937FFC28775FFCCCCCCFFBC8877FFAD4624FFC360 - 3EFFC07C65FFCBCCCCFF4545455C4242426CCFCFCFFFBC5B3BFFDD7D5BFFC962 - 40FFBD5330FFB44A26FFBC7259FFD1CFCFFFC7AEA5FFB24824FFB34925FFBD55 - 32FFBC5B3BFFC3C3C3FF4242426C3E3E3E6ECCCCCCFFB95737FFD5714DFFBF50 - 2AFFBD4E27FFB94B26FFDBDBDBFFDBDBDBFFB94C26FFBD4E27FFBD4E27FFC154 - 2EFFB95737FFC0C0C0FF3E3E3E6E3A3A3A61D0CFCFFFB9745DFFCF643EFFC954 - 2AFFC9542AFFC9542AFFBB4D27FFBB4D27FFC9542AFFC9542AFFC9542AFFC554 - 2CFFB9745DFFC2C0C0FF3A3A3A6137373747ACAAAAD7C09789FFBF5631FFD85F - 33FFD55A2DFFCB542AFFEEEEEEFFEEEEEEFFCB542AFFD55A2DFFD55A2DFFBC4F - 29FFBF9588FFA29F9FD7373737473434341953515186D4CECEFFB35F44FFC957 - 2FFFE16132FFD3592DFFEEEEEEFFEEEEEEFFD3592DFFE15F30FFC8532AFFB35F - 44FFD0C9C9FF5150508634343419303030002F2F2F48827E7EACDBD1D1FFAC57 - 3CFFB6461FFFD6592AFFE56230FFE56230FFD6592AFFB6461FFFAC573CFFDACF - CFFF817C7CAC2F2F2F48303030002E2E2E002C2C2C092626265C807979AFE4D6 - D6FFC69689FFAD644EFF943312FF943312FFAD644EFFC69689FFE3D6D6FF7F79 - 79AF2626265C2C2C2C092E2E2E002E2E2E002C2C2C001E1E1E091717174F3D3A - 3A92B2A6A6DCEBDADAFFEBDADAFFEBDADAFFEBDADAFFB2A6A6DC3D3A3A921717 - 174F1E1E1E092C2C2C002E2E2E002E2E2E002C2C2C001E1E1E00131313000D0D - 0D1D0B0B0B540B0B0B740B0B0B870B0B0B870B0B0B740B0B0B540D0D0D1D1313 - 13001E1E1E002C2C2C002E2E2E00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF007A7A7A117C7C7C547C7C7C677C7C7C547A7A - 7A1177777700555555000000A2000000A200000099000000A6000000A7210000 - A8A60000A8CC0000A8A60000A72165656557CACACAB8FDFDFDFFCACACAB86565 - 65575B5B5B005555550016168E0000009FCC0000993300009E0000009FA73F3F - D5E87272FEFF3F3FD5E800009FA74545456FF2F2F2FFF2F2F2FFF2F2F2FF4545 - 456F55555566555555662B2B7400000092B3000092CC00009200000092CC5656 - F5FF5656F5FF5656F5FF000092CC2525255E9F9F9FBDE4E4E4FF9F9F9FBD2525 - 255E474747005555550016167700000084CC00008B3300008600000084A71F1F - BEE83434EBFF1F1FBEE8000084A70E0E0E140B0B0B610B0B0B770B0B0B610E0E - 0E141010100055555500000080000000800000008B0000006E0000006B210000 - 67A6000067CC000067A600006B21FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF007A7A7A117C7C7C547C7C7C677C7C7C547A7A - 7A1177777700555555005555550055555500EA846200EB856329EC8664D0EC86 - 64FFEC8664D0EB856329FFFFFF0065656557CACACAB8FDFDFDFFCACACAB86565 - 65575B5B5B0055555500555555005555550079605700E27C5AD0EEA891FFF7CE - C1FFEEA891FFE27C5AD0FFFFFF004545456FF2F2F2FFF2F2F2FFF2F2F2FF4545 - 456F5454546654545466545454665454546654545466D46F4DFFF0C7BAFFF0C7 - BAFFF0C7BAFFD46F4DFFFFFFFF002525255E9F9F9FBDE4E4E4FF9F9F9FBD2525 - 255E45454500505050004C4C4C66505050006E554D00C4613FD0D7927BFFE8BF - B2FFD7927BFFC4613FD0FFFFFF000E0E0E140B0B0B610B0B0B770B0B0B610E0E - 0E1410101000414141004141416641414100B9563400B8553329B65331D0B653 - 31FFB65331D0B8553329FFFFFF000B0B0B000606060006060600060606000B0B - 0B002323230035353500353535663535350077463500B6533100B3502E00B350 - 2E00B3502E00B6533100FFFFFF000B0B0B000606060006060600060606000B0B - 0B00282828002828280028282866282828006E372600B1452300AE442200AE44 - 2200AE442200B1452300FFFFFF000B0B0B000606060006060600060606001111 - 11001A1A1A001A1A1A001A1A1A661A1A1A00B3462400B2462429B14523D0B145 - 23FFB14523D0B2462429FFFFFF000B0B0B000606060006060600080808000F0F - 0F000F0F0F000F0F0F000F0F0F660A0A0A0034180F00BD4B29D0DB9078FFF7CE - C1FFDB9078FFBD4B29D0FFFFFF000B0B0B000606060006060600070707000707 - 070007070700070707000606064D0505056605050566CC5331FFF0C7BAFFF0C7 - BAFFF0C7BAFFCC5331FFFFFFFF000B0B0B000606060006060600070707000707 - 0700070707000707070005050500030303003A1A1100DB5B39D0E4917AFFE8BF - B2FFE4917AFFDB5B39D0FFFFFF000B0B0B000606060006060600070707000707 - 070007070700070707000505050003030300E5613F00E7624029E86341D0E863 - 41FFE86341D0E7624029FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00 - } - end - object MainMenu: TMainMenu - Images = ImageList - left = 168 - top = 136 - object MnuFile: TMenuItem - Caption = 'File' - object MnuFileOpen: TMenuItem - Action = AcFileOpen - Bitmap.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF - FF00005D8C000064970000629300005E8E30005C8C7C0059879200598700005B - 8900005B8900005B8900005B8900005D8C0000669900FFFFFF00FFFFFF00FFFF - FF00005D8C0000659950006497991C7AA9C052A5CDE0005B89C1005B8900005B - 8900005B8900005B8900005B8900005D8C0000669900FFFFFF00FFFFFF00FFFF - FF00005E8D8E3591BDF169B8DDFA81CBECFF84CEEEFF005C8BEF005D8CBE005D - 8CBE005D8CBE005D8CBE005D8CBE005E8D8E00669900FFFFFF00FFFFFF00FFFF - FF00006699B287D1EFFF7FCAE9FF7FCAE9FF87D0EFFF267DA9FF8DD1F3FF8DD1 - F3FF8DD1F3FF8DD1F3FF90D4F5FF006699B200679B3EFFFFFF00FFFFFF00FFFF - FF00006FA7A48AD3F0FF82CDEBFF82CDEBFF8AD3F0FF267EABFF8ACEF0FF8ACE - F0FF8ACEF0FF8ACEF0FF8FD3F4FFF4B62EFF006FA7A4FFFFFF00FFFFFF00FFFF - FF000073AC9E8ED6F2FF87D0EDFF87D0EDFF8ED6F2FF2882AFFF8BCFF1FF8BCF - F1FF8BCFF1FF8BCFF1FF91D5F5FFFEC941FF0073AC9EFFFFFF00FFFFFF00FFFF - FF000076B09B92DAF4FF8BD4F0FF8BD4F0FF92DAF4FF2B85B3FF8DD1F3FF8DD1 - F3FF8DD1F3FF8DD1F3FF93D7F6FFEBEBDDFF0076B09BFFFFFF00FFFFFF00FFFF - FF000078B49797DEF6FF90D8F2FF90D8F2FF97DEF6FF2D89B7FF8FD3F5FF8FD3 - F5FF8FD3F5FF8FD3F5FF95D9F8FFF5F5EEFF0078B497FFFFFF00FFFFFF00FFFF - FF00007BB8949BE1F7FF94DBF4FF94DBF4FF9BE1F7FF308DBCFF90D4F6FF90D4 - F6FF90D4F6FF90D4F6FF97DBF9FFFEFEFDFF007BB894FFFFFF00FFFFFF00FFFF - FF00007DBB909EE5F9FF98DFF6FF98DFF6FF9EE5F9FF3290C0FF92D6F8FF92D6 - F8FF92D6F8FF92D6F8FF99DDFAFF007DBB90007DBB33FFFFFF00FFFFFF00FFFF - FF00007FBF8DA3E8FBFF9DE3F9FF9DE3F9FFA3E8FBFF3594C5FF94D8FAFF94D8 - FAFF94D8FAFF94D8FAFF9BDFFCFF007FBF8D007FBE00FFFFFF00FFFFFF00FFFF - FF000082C28AA6EBFCFFA1E6FBFFA1E6FBFFA6EBFCFF3C9DCFFF96DAFCFF96DA - FCFF96DAFCFF96DAFCFF9EE2FDFF0082C28A0082C200FFFFFF00FFFFFF00FFFF - FF000084C587A9EEFDFFA4E9FCFFA4E9FCFFAAEEFDFF42A1D1FF97DBFDFF97DB - FDFF97DBFDFF97DBFDFF9FE3FEFF0084C5870084C500FFFFFF00FFFFFF00FFFF - FF000085C885ACF1FFFFABEFFEFF95E2F8FF6EC9EDFF48A8D9FF98DCFEFF98DC - FEFF98DCFEFF98DCFEFFA1E5FFFF0085C8850085C800FFFFFF00FFFFFF00FFFF - FF000087CA8388DCF4FF60C0E9FF5FBFEAFF80D3F4FF9CE3FDFFA2E6FFFFA2E6 - FFFFA2E6FFFFA2E6FFFFA6EAFFFF0087CA830087CA00FFFFFF00FFFFFF00FFFF - FF000088CC610088CC810088CC810088CC810088CC810088CC810088CC810088 - CC810088CC810088CC810088CC810088CC610087CB00FFFFFF00 - } - end - object MnuFileReopen: TMenuItem - Caption = 'Recently opened files' - end - object MenuItem9: TMenuItem - Caption = '-' - end - object MnuDumpToFile: TMenuItem - Action = AcDumpToFile - end - object MenuItem4: TMenuItem - Caption = '-' - end - object MnuFileQuit: TMenuItem - Action = AcFileQuit - Bitmap.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 200000000000000400006400000064000000000000000000000000105500000B - 4FCC0007498A0005462400054700000648000006470000044500000445000004 - 45000004450000044500000445000004450000064800FFFFFF00001B64CC4174 - B8FF2A5094EC0A1A5ED300084A8A000648240006470000044500000445000004 - 45000004450000044500000445000004450000064800FFFFFF0000226DCC3F72 - B6FF225599FF3B6EB2FF2C5196EC0A1C60D3000749A4000648CC000648CC0006 - 48CC000648CC000648CC000648CC000648CC00074A99FFFFFF00002571CC4174 - B8FF2C5FA3FF2D60A4FF23569AFF3D70B4FF334179FFBEBEBEFFD5D5D5FFD8D8 - D8FFDBDBDBFFDCDCDCFFDDDDDDFFDDDDDDFF001258CCFFFFFF00002875CC4477 - BBFF2C5FA3FF3568ACFF2B5EA2FF2E61A5FF334B87FFBBBBBBFFD3D3D3FFD5D5 - D5FFD8D8D8FFDBDBDBFFDCDCDCFFDDDDDDFF001F68CCFFFFFF00002B79CC477A - BEFF2C5FA3FF376AAEFF2B5EA2FF376AAEFF33508CFFB8B8B8FFD0D0D0FFD3D3 - D3FFD5D5D5FFD8D8D8FFDBDBDBFFDCDCDCFF00246FCCFFFFFF00002E7DCC497C - C0FF09336FFF215090FF2B5EA2FF396CB0FF335290FFB5B5B5FFCCCCCCFFD0D0 - D0FFD3D3D3FFD5D5D5FFD8D8D8FFDBDBDBFF002774CCFFFFFF00003181CC4C7F - C3FFBBBBBBFF22518CFF2C5FA3FF3B6EB2FF335593FFB3B3B3FFC9C9C9FFCCCC - CCFFD0D0D0FFD3D3D3FFD5D5D5FFD8D8D8FF002B78CCFFFFFF00003485CC5083 - C7FF1D5094FF3265A9FF2D60A4FF3D70B4FF335897FFB0B0B0FFC7C7C7FFC9C9 - C9FFCCCCCCFFD0D0D0FFD3D3D3FFD5D5D5FF002E7DCCFFFFFF00003688CC5386 - CAFF295CA0FF3F72B6FF3063A7FF3F72B6FF335A9AFFAEAEAEFFC4C4C4FFC7C7 - C7FFC9C9C9FFCCCCCCFFD0D0D0FFD3D3D3FF003181CCFFFFFF0000398BCC5588 - CCFF275A9EFF4174B8FF3164A8FF4174B8FF335D9EFFACACACFFC1C1C1FFC4C4 - C4FFC7C7C7FFC9C9C9FFCCCCCCFFD0D0D0FF003485CCFFFFFF00003B8ECC588B - CFFF1A4D91FF4376BAFF3265A9FF4376BAFF335FA1FFAAAAAAFFBFBFBFFFC1C1 - C1FFC4C4C4FFC7C7C7FFC9C9C9FFCCCCCCFF003789CCFFFFFF00003D91CC5D90 - D4FF3568ACFF285B9FFF1A4D91FF4477BBFF3361A4FFA9A9A9FFBDBDBDFFBFBF - BFFFC1C1C1FFC4C4C4FFC7C7C7FFC9C9C9FF003A8DCCFFFFFF00003F938A0E4A - 9CD33E75BFEC5487CBFF3669ADFF23569AFF3363A6FFA9A9A9FFBCBCBCFFBDBD - BDFFBFBFBFFFC1C1C1FFC4C4C4FFC7C7C7FF003C90CCFFFFFF00003F9300003F - 9324003F938A0E4B9CD33F76C0EC5D90D4FF3365A9FFA0A0A0FFA9A9A9FFA9A9 - A9FFAAAAAAFFACACACFFAEAEAEFFB0B0B0FF003E93CCFFFFFF00003F9300003F - 9300003F9300003F9424003F948A003E93CC004095CC004095CC004095CC0040 - 95CC004095CC004095CC004095CC004095CC00409599FFFFFF00 - } - end - end - object MnuRecord: TMenuItem - Caption = 'Record' - object MnuFind: TMenuItem - Action = AcFind - AutoCheck = True - Bitmap.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 040004040400040404000404045C090909892525252CFFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 040004040400040404443B3838A2E8D8D8FF32323276FFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 04000404043328272799D9CECEFF605C5C913A3A3A4DFFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 04251A1A1A8FC8C1C1FF4F4D4D88393939383C3C3C00FFFFFF001E1E1E000E0E - 0E000404041604040456040404790404048704040479040404560404042A0F0F - 0F86B8B5B5FF4241417E3838382A3A3A3A003C3C3C00FFFFFF001E1E1E001111 - 112A2826257D9D9791A5EEE8E3C4F9F3EDD6EFEAE5C5A3A09EA92827278AACAC - ACFF373737753737371F393939003A3A3A003C3C3C00FFFFFF00262626143B3A - 3874D7C9BCAFF3E6D9CBF6EDE4CEF6EDE4CEF6EDE4CEF7EFE6D1E4DED9C84544 - 437D3434342438383800393939003A3A3A003C3C3C00FFFFFF0031313149A89D - 9397EAD5BFC3F5E9DFCBF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6ECE2CEADA6 - 9E9D3131314931313100313131003131310031313100FFFFFF0038383865E1CF - BCB1E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEE7D8 - CAB83838386538383800383838003838380038383800FFFFFF003E3E3E6FE9D4 - BEBEE8D2BBC0E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEEDDB - C8C53E3E3E6F3E3E3E003E3E3E003E3E3E003E3E3E00FFFFFF0043434360E0CB - B6ACE8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E4D3 - C1B24343436043434300434343004343430043434300FFFFFF0049494943AD9F - 918EE8D2BBC0F1E3D5C8F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4 - 97914949494349494900494949004949490049494900FFFFFF004D4D4D115F5D - 5A64D5C1AEA1EBD8C4C2F6ECE2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D - 5B644D4D4D114C4C4C004C4C4C004C4C4C004C4C4C00FFFFFF004E4E4E005151 - 512163605E62B1A3948BE6D5C5AFF4EADFC7EDE3D9B5B6ACA28E63605E625151 - 51214E4E4E004E4E4E004E4E4E004E4E4E004E4E4E00FFFFFF004E4E4E005151 - 510054545411555555405555555A555555655555555A55555540545454115151 - 51004E4E4E004E4E4E00295727000569000007710000FFFFFF00 - } - end - end - object MnuHelp: TMenuItem - Caption = 'Help' - object MenuItem2: TMenuItem - Action = AcAbout - Bitmap.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 20000000000000040000640000006400000000000000000000002E2E2E002C2C - 2C001E1E1E00131313000D0D0D1D0B0B0B540B0B0B740B0B0B870B0B0B870B0B - 0B740B0B0B540D0D0D1D131313001E1E1E002C2C2C002E2E2E002E2E2E002C2C - 2C001E1E1E091717174F3D3A3A92B2A6A6DCEBDADAFFEBDADAFFEBDADAFFEBDA - DAFFB2A6A6DC3D3A3A921717174F1E1E1E092C2C2C002E2E2E002E2E2E002C2C - 2C092626265C807979AFE4D6D6FFC69689FFAD644EFF943312FF943312FFAD64 - 4EFFC69689FFE3D6D6FF7F7979AF2626265C2C2C2C092E2E2E00303030002F2F - 2F48827E7EACDBD1D1FFAC573CFFB6461FFFD6592AFFE56230FFE56230FFD659 - 2AFFB6461FFFAC573CFFDACFCFFF817C7CAC2F2F2F4830303000343434195351 - 5186D4CECEFFB35F44FFC9572FFFE16132FFD3592DFFEEEEEEFFEEEEEEFFD359 - 2DFFE15F30FFC8532AFFB35F44FFD0C9C9FF515050863434341937373747ACAA - AAD7C09789FFBF5631FFD85F33FFD55A2DFFCB542AFFEEEEEEFFEEEEEEFFCB54 - 2AFFD55A2DFFD55A2DFFBC4F29FFBF9588FFA29F9FD7373737473A3A3A61D0CF - CFFFB9745DFFCF643EFFC9542AFFC9542AFFC9542AFFBB4D27FFBB4D27FFC954 - 2AFFC9542AFFC9542AFFC5542CFFB9745DFFC2C0C0FF3A3A3A613E3E3E6ECCCC - CCFFB95737FFD5714DFFBF502AFFBD4E27FFB94B26FFDBDBDBFFDBDBDBFFB94C - 26FFBD4E27FFBD4E27FFC1542EFFB95737FFC0C0C0FF3E3E3E6E4242426CCFCF - CFFFBC5B3BFFDD7D5BFFC96240FFBD5330FFB44A26FFBC7259FFD1CFCFFFC7AE - A5FFB24824FFB34925FFBD5532FFBC5B3BFFC3C3C3FF4242426C4545455CDBDC - DCFFC07C65FFDF805EFFCF6947FFCF6947FFCA6442FFC05937FFC28775FFCCCC - CCFFBC8877FFAD4624FFC3603EFFC07C65FFCBCCCCFF4545455C48484842BEBF - BFD4C9A295FFD57452FFE2815FFFD26C4AFFD5A291FFD5A291FFE6C2B6FFFFFF - FFFFE0AD9CFFDF7C5AFFD16E4CFFC7A194FFB2B3B3D4484848424B4B4B176C6C - 6C7CDFE0E0FFC8755AFFE28361FFDC7A58FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - FFFFE2987FFFDF7E5CFFC8755AFFD8D8D8FF6969697C4B4B4B174E4E4E004E4E - 4E3F9D9D9DA2DFDFDFFFCB795EFFDB7A58FFEE906EFFF49674FFF49573FFED8E - 6CFFDA7856FFCB795EFFDBDCDCFF999999A24E4E4E3F4E4E4E004F4F4F005050 - 50075151514D9F9F9FA1E6E6E6FFD7B0A3FFD08C75FFCD6C4BFFCD6C4BFFD08C - 75FFD6AFA2FFE3E4E4FF9D9D9DA15151514D505050074F4F4F004F4F4F005050 - 5000525252075353533D73737378C8C8C8D2EAEAEAFFE6E6E6FFE6E6E6FFEAEA - EAFFC7C7C7D2727272785353533D52525207505050004F4F4F004F4F4F005050 - 50005252520053535300545454155555553E5555555555555563555555635555 - 55555555553E545454155353530052525200505050004F4F4F00 - } - end - end - end - object ActionList: TActionList - Images = ImageList - left = 168 - top = 64 - object AcFileOpen: TAction - Caption = 'Open' - Hint = 'Open xls file' - ImageIndex = 0 - OnExecute = AcFileOpenExecute - ShortCut = 16463 - end - object AcFileQuit: TAction - Caption = 'Quit' - Hint = 'Quit application' - ImageIndex = 1 - OnExecute = AcFileQuitExecute - ShortCut = 32856 - end - object AcFind: TAction - AutoCheck = True - Caption = 'Find' - Hint = 'Find record' - ImageIndex = 2 - OnExecute = AcFindExecute - ShortCut = 16454 - end - object AcFindClose: TAction - ImageIndex = 3 - OnExecute = AcFindCloseExecute - end - object AcFindNext: TAction - ImageIndex = 4 - OnExecute = AcFindNextExecute - end - object AcFindPrev: TAction - ImageIndex = 5 - OnExecute = AcFindPrevExecute - end - object AcAbout: TAction - Caption = 'About...' - ImageIndex = 6 - OnExecute = AcAboutExecute - end - object AcNodeExpand: TAction - Caption = 'Expand node' - Hint = 'Expand current node' - ImageIndex = 8 - OnExecute = AcNodeExpandExecute - OnUpdate = AcNodeExpandUpdate - end - object AcNodeCollapse: TAction - Caption = 'Collapse node' - Hint = 'Collapse current node' - ImageIndex = 7 - OnExecute = AcNodeCollapseExecute - OnUpdate = AcNodeCollapseUpdate - end - object AcDumpToFile: TAction - Caption = 'Dump to text file' - OnExecute = AcDumpToFileExecute - end - end - object OpenDialog: TOpenDialog - DefaultExt = '.xls' - Filter = 'Excel files (*.xls)|*.xls' - left = 160 - top = 296 - end - object RecentFilesPopupMenu: TPopupMenu - left = 160 - top = 208 - object MenuItem1: TMenuItem - Caption = 'New Item1' - end - end - object TreePopupMenu: TPopupMenu - Images = ImageList - left = 160 - top = 392 - object MenuItem3: TMenuItem - Action = AcNodeExpand - Bitmap.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000B0B0B000606 - 060006060600070707000707070007070700070707000505050003030300E561 - 3F00E7624029E86341D0E86341FFE86341D0E7624029FFFFFF000B0B0B000606 - 0600060606000707070007070700070707000707070005050500030303003A1A - 1100DB5B39D0E4917AFFE8BFB2FFE4917AFFDB5B39D0FFFFFF000B0B0B000606 - 060006060600070707000707070007070700070707000606064D050505660505 - 0566CC5331FFF0C7BAFFF0C7BAFFF0C7BAFFCC5331FFFFFFFF000B0B0B000606 - 060006060600080808000F0F0F000F0F0F000F0F0F000F0F0F660A0A0A003418 - 0F00BD4B29D0DB9078FFF7CEC1FFDB9078FFBD4B29D0FFFFFF000B0B0B000606 - 06000606060006060600111111001A1A1A001A1A1A001A1A1A661A1A1A00B346 - 2400B2462429B14523D0B14523FFB14523D0B2462429FFFFFF000B0B0B000606 - 060006060600060606000B0B0B00282828002828280028282866282828006E37 - 2600B1452300AE442200AE442200AE442200B1452300FFFFFF000B0B0B000606 - 060006060600060606000B0B0B00232323003535350035353566353535007746 - 3500B6533100B3502E00B3502E00B3502E00B6533100FFFFFF000E0E0E140B0B - 0B610B0B0B770B0B0B610E0E0E1410101000414141004141416641414100B956 - 3400B8553329B65331D0B65331FFB65331D0B8553329FFFFFF002525255E9F9F - 9FBDE4E4E4FF9F9F9FBD2525255E45454500505050004C4C4C66505050006E55 - 4D00C4613FD0D7927BFFE8BFB2FFD7927BFFC4613FD0FFFFFF004545456FF2F2 - F2FFF2F2F2FFF2F2F2FF4545456F545454665454546654545466545454665454 - 5466D46F4DFFF0C7BAFFF0C7BAFFF0C7BAFFD46F4DFFFFFFFF0065656557CACA - CAB8FDFDFDFFCACACAB8656565575B5B5B005555550055555500555555007960 - 5700E27C5AD0EEA891FFF7CEC1FFEEA891FFE27C5AD0FFFFFF007A7A7A117C7C - 7C547C7C7C677C7C7C547A7A7A1177777700555555005555550055555500EA84 - 6200EB856329EC8664D0EC8664FFEC8664D0EB856329FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 - } - end - object MenuItem5: TMenuItem - Action = AcNodeCollapse - Bitmap.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000E0E0E140B0B - 0B610B0B0B770B0B0B610E0E0E14101010005555550000008000000080000000 - 8B0000006E0000006B21000067A6000067CC000067A600006B212525255E9F9F - 9FBDE4E4E4FF9F9F9FBD2525255E474747005555550016167700000084CC0000 - 8B3300008600000084A71F1FBEE83434EBFF1F1FBEE8000084A74545456FF2F2 - F2FFF2F2F2FFF2F2F2FF4545456F55555566555555662B2B7400000092B30000 - 92CC00009200000092CC5656F5FF5656F5FF5656F5FF000092CC65656557CACA - CAB8FDFDFDFFCACACAB8656565575B5B5B005555550016168E0000009FCC0000 - 993300009E0000009FA73F3FD5E87272FEFF3F3FD5E800009FA77A7A7A117C7C - 7C547C7C7C677C7C7C547A7A7A1177777700555555000000A2000000A2000000 - 99000000A6000000A7210000A8A60000A8CC0000A8A60000A721FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 - } - end - object MenuItem6: TMenuItem - Caption = '-' - end - object MenuItem7: TMenuItem - Action = AcFind - AutoCheck = True - Bitmap.Data = { - 36040000424D3604000000000000360000002800000010000000100000000100 - 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF - FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 040004040400040404000404045C090909892525252CFFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 040004040400040404443B3838A2E8D8D8FF32323276FFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 04000404043328272799D9CECEFF605C5C913A3A3A4DFFFFFF001E1E1E000E0E - 0E00040404000404040004040400040404000404040004040400040404000404 - 04251A1A1A8FC8C1C1FF4F4D4D88393939383C3C3C00FFFFFF001E1E1E000E0E - 0E000404041604040456040404790404048704040479040404560404042A0F0F - 0F86B8B5B5FF4241417E3838382A3A3A3A003C3C3C00FFFFFF001E1E1E001111 - 112A2826257D9D9791A5EEE8E3C4F9F3EDD6EFEAE5C5A3A09EA92827278AACAC - ACFF373737753737371F393939003A3A3A003C3C3C00FFFFFF00262626143B3A - 3874D7C9BCAFF3E6D9CBF6EDE4CEF6EDE4CEF6EDE4CEF7EFE6D1E4DED9C84544 - 437D3434342438383800393939003A3A3A003C3C3C00FFFFFF0031313149A89D - 9397EAD5BFC3F5E9DFCBF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6ECE2CEADA6 - 9E9D3131314931313100313131003131310031313100FFFFFF0038383865E1CF - BCB1E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEE7D8 - CAB83838386538383800383838003838380038383800FFFFFF003E3E3E6FE9D4 - BEBEE8D2BBC0E8D2BBC0F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEEDDB - C8C53E3E3E6F3E3E3E003E3E3E003E3E3E003E3E3E00FFFFFF0043434360E0CB - B6ACE8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E8D2BBC0E4D3 - C1B24343436043434300434343004343430043434300FFFFFF0049494943AD9F - 918EE8D2BBC0F1E3D5C8F6EDE4CEF6EDE4CEF6EDE4CEF6EDE4CEF2E4D6C8B0A4 - 97914949494349494900494949004949490049494900FFFFFF004D4D4D115F5D - 5A64D5C1AEA1EBD8C4C2F6ECE2CDF6EDE4CEF6EDE4CEF6ECE2CDD9C8B8A4605D - 5B644D4D4D114C4C4C004C4C4C004C4C4C004C4C4C00FFFFFF004E4E4E005151 - 512163605E62B1A3948BE6D5C5AFF4EADFC7EDE3D9B5B6ACA28E63605E625151 - 51214E4E4E004E4E4E004E4E4E004E4E4E004E4E4E00FFFFFF004E4E4E005151 - 510054545411555555405555555A555555655555555A55555540545454115151 - 51004E4E4E004E4E4E00295727000569000007710000FFFFFF00 - } - end - end - object SaveDialog: TSaveDialog - DefaultExt = '.txt' - Filter = 'Text files (*.txt)|*.txt' - left = 289 - top = 296 - end -end diff --git a/components/fpspreadsheet/reference/BIFFExplorer/bemain.pas b/components/fpspreadsheet/reference/BIFFExplorer/bemain.pas deleted file mode 100644 index f7c2a90ea..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/bemain.pas +++ /dev/null @@ -1,1472 +0,0 @@ -unit beMain; - -{$mode objfpc}{$H+} - -interface - -uses - ActnList, Classes, ComCtrls, ExtCtrls, Grids, Menus, StdCtrls, SysUtils, - FileUtil, Forms, Controls, Graphics, Dialogs, Buttons, Types, VirtualTrees, - {$ifdef USE_NEW_OLE} - fpolebasic, - {$else} - fpolestorage, - {$endif} - fpstypes, KHexEditor, - mrumanager, beTypes, beBIFFGrid; - -type - - { TMainForm } - TMainForm = class(TForm) - AcFileOpen: TAction; - AcFileQuit: TAction; - AcFind: TAction; - AcFindNext: TAction; - AcFindPrev: TAction; - AcAbout: TAction; - AcFindClose: TAction; - AcNodeExpand: TAction; - AcNodeCollapse: TAction; - AcDumpToFile: TAction; - ActionList: TActionList; - BIFFTree: TVirtualStringTree; - CbFind: TComboBox; - CbHexAddress: TCheckBox; - CbHexEditorLineSize: TComboBox; - CbHexSingleBytes: TCheckBox; - ImageList: TImageList; - HexEditor: TKHexEditor; - MainMenu: TMainMenu; - AnalysisDetails: TMemo; - MenuItem1: TMenuItem; - MenuItem3: TMenuItem; - MenuItem5: TMenuItem; - MenuItem6: TMenuItem; - MenuItem7: TMenuItem; - MnuDumpToFile: TMenuItem; - MenuItem9: TMenuItem; - MnuFind: TMenuItem; - MnuRecord: TMenuItem; - MnuFileReopen: TMenuItem; - MenuItem4: TMenuItem; - MnuHelp: TMenuItem; - MenuItem2: TMenuItem; - MnuFileQuit: TMenuItem; - MnuFileOpen: TMenuItem; - MnuFile: TMenuItem; - OpenDialog: TOpenDialog; - PageControl: TPageControl; - DetailPanel: TPanel; - FindPanel: TPanel; - HexEditorParamsPanel: TPanel; - SaveDialog: TSaveDialog; - SpeedButton3: TSpeedButton; - TreePopupMenu: TPopupMenu; - TreePanel: TPanel; - BtnFindNext: TSpeedButton; - BtnFindPrev: TSpeedButton; - RecentFilesPopupMenu: TPopupMenu; - BtnCloseFind: TSpeedButton; - Splitter1: TSplitter; - HexSplitter: TSplitter; - PgAnalysis: TTabSheet; - PgValues: TTabSheet; - DetailsSplitter: TSplitter; - StatusBar: TStatusBar; - ToolButton3: TToolButton; - ToolButton4: TToolButton; - ValueGrid: TStringGrid; - ToolBar: TToolBar; - ToolButton1: TToolButton; - ToolButton2: TToolButton; - procedure AcAboutExecute(Sender: TObject); - procedure AcDumpToFileExecute(Sender: TObject); - procedure AcFileOpenExecute(Sender: TObject); - procedure AcFileQuitExecute(Sender: TObject); - procedure AcFindCloseExecute(Sender: TObject); - procedure AcFindExecute(Sender: TObject); - procedure AcFindNextExecute(Sender: TObject); - procedure AcFindPrevExecute(Sender: TObject); - procedure AcNodeCollapseExecute(Sender: TObject); - procedure AcNodeCollapseUpdate(Sender: TObject); - procedure AcNodeExpandExecute(Sender: TObject); - procedure AcNodeExpandUpdate(Sender: TObject); - procedure BIFFTreeBeforeCellPaint(Sender: TBaseVirtualTree; - TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; - CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect); - procedure BIFFTreeFocusChanged(Sender: TBaseVirtualTree; - Node: PVirtualNode; Column: TColumnIndex); - procedure BIFFTreeFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode); - procedure BIFFTreeGetNodeDataSize(Sender: TBaseVirtualTree; - var NodeDataSize: Integer); - procedure BIFFTreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; - Column: TColumnIndex; TextType: TVSTTextType; var CellText: String); -// procedure BIFFTreeInitNode(Sender: TBaseVirtualTree; ParentNode, -// Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates); - procedure BIFFTreePaintText(Sender: TBaseVirtualTree; - const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; - TextType: TVSTTextType); - procedure CbFindChange(Sender: TObject); - procedure CbFindKeyPress(Sender: TObject; var Key: char); - procedure CbHexAddressChange(Sender: TObject); - procedure CbHexEditorLineSizeChange(Sender: TObject); - procedure CbHexSingleBytesChange(Sender: TObject); - procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); - procedure FormCreate(Sender: TObject); - procedure FormDestroy(Sender: TObject); - procedure FormDropFiles(Sender: TObject; const FileNames: array of String); - procedure FormShow(Sender: TObject); - procedure HexEditorClick(Sender: TObject); - procedure HexEditorKeyDown(Sender: TObject; var Key: Word; - Shift: TShiftState); - procedure ListViewSelectItem(Sender: TObject; Item: TListItem; - Selected: Boolean); - procedure PageControlChange(Sender: TObject); - procedure ValueGridClick(Sender: TObject); - procedure ValueGridPrepareCanvas(Sender: TObject; ACol, ARow: Integer; - AState: TGridDrawState); - - private - MemStream: TMemoryStream; - OLEStorage: TOLEStorage; - FFileName: String; - FFormat: TsSpreadsheetFormat; - FBuffer: TBIFFBuffer; - FCurrOffset: Integer; - FXFIndex: Integer; - FFontIndex: Integer; - FFormatIndex: Integer; - FRowIndex: Integer; - FExternSheetIndex: Integer; - FAnalysisGrid: TBIFFGrid; - FMRUMenuManager : TMRUMenuManager; - procedure AddToHistory(const AText: String); - procedure AnalysisGridDetails(Sender: TObject; ADetails: TStrings); - procedure AnalysisGridPrepareCanvas(Sender: TObject; ACol, ARow: Integer; - AState: TGridDrawState); - procedure AnalysisGridSelection(Sender: TObject; ACol, ARow: Integer); - procedure DumpToFile(const AFileName: String); - procedure ExecFind(ANext, AKeep: Boolean); - function GetBIFFNodeData: PBiffNodeData; - function GetRecType: Word; - function GetValueGridDataSize: Integer; - procedure LoadFile(const AFileName: String); overload; - procedure LoadFile(const AFileName: String; AFormat: TsSpreadsheetFormat); overload; - procedure MRUMenuManagerRecentFile(Sender:TObject; const AFileName:string); - procedure PopulateAnalysisGrid; - procedure PopulateHexDump; - procedure PopulateValueGrid; - procedure ReadCmdLine; - procedure ReadFromIni; - procedure ReadFromStream(AStream: TStream); - procedure UpdateCaption; - procedure UpdateCmds; - procedure UpdateStatusbar; - procedure WriteToIni; - - public - procedure BeforeRun; - end; - -var - MainForm: TMainForm; - -implementation - -{$R *.lfm} - -uses - IniFiles, LazUTF8, LazFileUtils, Math, StrUtils, LCLType, - KFunctions, - fpsUtils, - beUtils, beBIFFUtils, beAbout; - -const - VALUE_ROW_INDEX = 1; - VALUE_ROW_BITS = 2; - VALUE_ROW_BYTE = 3; - VALUE_ROW_SHORTINT = 4; - VALUE_ROW_WORD = 5; - VALUE_ROW_SMALLINT = 6; - VALUE_ROW_DWORD = 7; - VALUE_ROW_LONGINT = 8; - VALUE_ROW_QWORD = 9; - VALUE_ROW_INT64 = 10; - VALUE_ROW_SINGLE = 11; - VALUE_ROW_DOUBLE = 12; - VALUE_ROW_ANSISTRING = 13; - VALUE_ROW_PANSICHAR = 14; - VALUE_ROW_WIDESTRING = 15; - VALUE_ROW_PWIDECHAR = 16; - - MAX_HISTORY = 16; - - -{ TMyHexEditor } - -type - TMyHexEditor = class(TKHexEditor); - - (* -{ Virtual tree nodes } - -type - TObjectNodeData = record - Data: TObject; - end; - PObjectNodeData = ^TObjectNodeData; - *) - -{ TMainForm } - -procedure TMainForm.AcAboutExecute(Sender: TObject); -var - F: TAboutForm; -begin - F := TAboutForm.Create(nil); - try - F.ShowModal; - finally - F.Free; - end; -end; - - -procedure TMainForm.AcDumpToFileExecute(Sender: TObject); -begin - if FFileName = '' then - exit; - - with SaveDialog do begin - FileName := ChangeFileExt(ExtractFileName(FFileName), '') + '_dumped.txt'; - if Execute then - DumpToFile(FileName); - end; -end; - - -procedure TMainForm.AcFileOpenExecute(Sender: TObject); -begin - with OpenDialog do begin - if Execute then LoadFile(FileName); - end; -end; - - -procedure TMainForm.AcFileQuitExecute(Sender: TObject); -begin - Close; -end; - - -procedure TMainForm.AcFindCloseExecute(Sender: TObject); -begin - AcFind.Checked := false; - FindPanel.Hide; -end; - - -procedure TMainForm.AcFindExecute(Sender: TObject); -begin - if AcFind.Checked then begin - FindPanel.Show; - CbFind.SetFocus; - end else begin - FindPanel.Hide; - end; -end; - - -procedure TMainForm.AcFindNextExecute(Sender: TObject); -begin - ExecFind(true, false); -end; - - -procedure TMainForm.AcFindPrevExecute(Sender: TObject); -begin - ExecFind(false, false); -end; - - -procedure TMainForm.AcNodeCollapseExecute(Sender: TObject); -var - node: PVirtualNode; -begin - node := BiffTree.FocusedNode; - if node <> nil then begin - if BiffTree.GetNodeLevel(node) > 0 then - node := node^.Parent; - BiffTree.Expanded[node] := false; - end; -end; - -procedure TMainForm.AcNodeCollapseUpdate(Sender: TObject); -var - node: PVirtualNode; -begin - node := BiffTree.FocusedNode; - if node <> nil then begin - if BiffTree.GetNodeLevel(node) > 0 then - node := node^.Parent; - end; - AcNodeCollapse.Enabled := (node <> nil) and BiffTree.Expanded[node]; -end; - - -procedure TMainForm.AcNodeExpandExecute(Sender: TObject); -var - node: PVirtualNode; -begin - node := BiffTree.FocusedNode; - if node <> nil then begin - if BiffTree.GetNodeLevel(node) > 0 then - node := node^.Parent; - BiffTree.Expanded[node] := true; - end; -end; - - -procedure TMainForm.AcNodeExpandUpdate(Sender: TObject); -var - node: PVirtualNode; -begin - node := BiffTree.FocusedNode; - if node <> nil then begin - if BiffTree.GetNodeLevel(node) > 0 then - node := node^.Parent; - end; - AcNodeExpand.Enabled := (node <> nil) and not BiffTree.Expanded[node]; -end; - -procedure TMainForm.AddToHistory(const AText: String); -begin - if (AText <> '') and (CbFind.Items.IndexOf(AText) = -1) then begin - CbFind.Items.Insert(0, AText); - while CbFind.Items.Count > MAX_HISTORY do - CbFind.Items.Delete(CbFind.Items.Count-1); - end; -end; - - -procedure TMainForm.AnalysisGridDetails(Sender: TObject; ADetails: TStrings); -begin - AnalysisDetails.Lines.Assign(ADetails); -end; - - -procedure TMainForm.AnalysisGridPrepareCanvas(Sender: TObject; ACol, - ARow: Integer; AState: TGridDrawState); -begin - if ARow = 0 then FAnalysisGrid.Canvas.Font.Style := [fsBold]; -end; - - -procedure TMainForm.AnalysisGridSelection(Sender: TObject; ACol, ARow: Integer); -var - s: String; -begin - if ARow < FAnalysisGrid.RowCount then - begin - s := FAnalysisGrid.Cells[0, ARow]; - if s <> '' then - begin - FCurrOffset := StrToInt(s); - PopulateValueGrid; - UpdateStatusbar; - end; - end; -end; - - -procedure TMainForm.BeforeRun; -begin - ReadFromIni; - ReadCmdLine; -end; - - -procedure TMainForm.BIFFTreeBeforeCellPaint(Sender: TBaseVirtualTree; - TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; - CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect); -var - s: String; -begin - if (Sender.GetNodeLevel(Node) = 0) and (Column = 0) then begin - // Left-align parent nodes (column 0 is right-aligned) - BiffTreeGetText(Sender, Node, 0, ttNormal, s); - TargetCanvas.Font.Style := [fsBold]; - ContentRect.Right := CellRect.Left + TargetCanvas.TextWidth(s) + 30; - end; -end; - - -procedure TMainForm.BIFFTreeFocusChanged(Sender: TBaseVirtualTree; - Node: PVirtualNode; Column: TColumnIndex); -var - data: PBiffNodeData; - n: Word; -begin - if Node^.Parent = Sender.RootNode then - begin - HexEditor.Clear; - for n:=1 to ValueGrid.RowCount-1 do - begin - ValueGrid.Cells[1, n] := ''; - ValueGrid.Cells[2, n] := ''; - end; - FAnalysisGrid.RowCount := 2; - FAnalysisGrid.Rows[1].Clear; - AnalysisDetails.Lines.Clear; - exit; - end; - - data := Sender.GetNodeData(Node); - - // Move to start of record + 2 bytes to skip record type ID. - MemStream.Position := PtrInt(data^.Offset) + 2; - - // Read size of record - n := WordLEToN(MemStream.ReadWord); - - // Read record data - SetLength(FBuffer, n); - if n > 0 then - MemStream.ReadBuffer(FBuffer[0], n); - - // Update user interface - if (BiffTree.FocusedNode <> nil) and (BiffTree.GetNodeLevel(BiffTree.FocusedNode) > 0) - then begin - Statusbar.Panels[0].Text := Format('Record ID: $%.4x', [data^.RecordID]); - Statusbar.Panels[1].Text := data^.RecordName; - Statusbar.Panels[2].Text := Format('Record size: %d bytes', [n]); - Statusbar.Panels[3].Text := ''; - end else begin - Statusbar.Panels[0].Text := ''; - Statusbar.Panels[1].Text := data^.RecordName; - Statusbar.Panels[2].Text := ''; - Statusbar.Panels[3].Text := ''; - end; - PopulateHexDump; - PageControlChange(nil); -end; - - -procedure TMainForm.BIFFTreeFreeNode(Sender: TBaseVirtualTree; - Node: PVirtualNode); -var - data: PBiffNodeData; -begin - data := Sender.GetNodeData(Node); - if data <> nil then - begin - data^.RecordName := ''; - data^.RecordDescription := ''; - end; -end; - - -procedure TMainForm.BIFFTreeGetNodeDataSize(Sender: TBaseVirtualTree; - var NodeDataSize: Integer); -begin - NodeDataSize := SizeOf(TBiffNodeData); -end; - - -procedure TMainForm.BIFFTreeGetText(Sender: TBaseVirtualTree; - Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; - var CellText: String); -var - data: PBiffNodeData; -begin - CellText := ''; - data := Sender.GetNodeData(Node); - if data <> nil then - case Sender.GetNodeLevel(Node) of - 0: if Column = 0 then CellText := data^.RecordName; - 1: case Column of - 0: CellText := IntToStr(data^.Offset); - 1: CellText := Format('$%.4x', [data^.RecordID]); - 2: CellText := data^.RecordName; - 3: if data^.Index > -1 then CellText := IntToStr(data^.Index); - 4: cellText := data^.RecordDescription; - end; - end; -end; - - -procedure TMainForm.BIFFTreePaintText(Sender: TBaseVirtualTree; - const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; - TextType: TVSTTextType); -begin - // Paint parent node in bold font. - if (Sender.GetNodeLevel(Node) = 0) and (Column = 0) then - TargetCanvas.Font.Style := [fsBold]; -end; - - -procedure TMainForm.CbFindChange(Sender: TObject); -begin - ExecFind(true, true); -end; - - -procedure TMainForm.CbFindKeyPress(Sender: TObject; var Key: char); -begin - if Key = #13 then - ExecFind(true, false); -end; - -procedure TMainForm.CbHexAddressChange(Sender: TObject); -begin - if CbHexAddress.Checked then - begin - HexEditor.AddressMode := eamHex; - HexEditor.AddressPrefix := '$'; - end else - begin - HexEditor.AddressMode := eamDec; - HexEditor.AddressPrefix := ''; - end; - CbHexEditorLineSizeChange(nil); -end; - -procedure TMainForm.CbHexEditorLineSizeChange(Sender: TObject); -begin - case CbHexEditorLineSize.ItemIndex of - 0: HexEditor.LineSize := IfThen(HexEditor.AddressMode = eamHex, 16, 10); - 1: HexEditor.LineSize := IfThen(HexEditor.AddressMode = eamHex, 32, 20); - end; -end; - -procedure TMainForm.CbHexSingleBytesChange(Sender: TObject); -begin - HexEditor.DigitGrouping := IfThen(CbHexSingleBytes.Checked, 1, 2); -end; - -procedure TMainForm.DumpToFile(const AFileName: String); -var - list: TStringList; - parentnode, node: PVirtualNode; - parentdata, data: PBiffNodeData; -begin - list := TStringList.Create; - try - parentnode := BiffTree.GetFirst; - while parentnode <> nil do begin - parentdata := BiffTree.GetNodeData(parentnode); - list.Add(parentdata^.RecordName); - node := BIffTree.GetFirstChild(parentnode); - while node <> nil do begin - data := BiffTree.GetNodeData(node); - List.Add(Format(' %.04x %s (%s)', [data^.RecordID, data^.RecordName, data^.RecordDescription])); - node := BiffTree.GetNextSibling(node); - end; - List.Add(''); - parentnode := BiffTree.GetNextSibling(parentnode); - end; - - list.SaveToFile(AFileName); - finally - list.Free; - end; -end; - - -procedure TMainForm.ExecFind(ANext, AKeep: Boolean); -var - s: String; - node, node0: PVirtualNode; - - function GetRecordname(ANode: PVirtualNode; UseLowercase: Boolean = true): String; - var - data: PBIffNodeData; - begin - data := BiffTree.GetNodeData(ANode); - if Assigned(data) then begin - if UseLowercase then - Result := lowercase(data^.RecordName) - else - Result := data^.RecordName; - end else - Result := ''; - end; - - function GetNextNode(ANode: PVirtualNode): PVirtualNode; - var - nextparent: PVirtualNode; - begin - Result := BiffTree.GetNextSibling(ANode); - if (Result = nil) and (ANode <> nil) then begin - nextparent := BiffTree.GetNextSibling(ANode^.Parent); - if nextparent = nil then - nextparent := BiffTree.GetFirst; - Result := BiffTree.GetFirstChild(nextparent); - end; - end; - - function GetPrevNode(ANode: PVirtualNode): PVirtualNode; - var - prevparent: PVirtualNode; - begin - Result := BiffTree.GetPreviousSibling(ANode); - if (Result = nil) and (ANode <> nil) then begin - prevparent := BiffTree.GetPreviousSibling(ANode^.Parent); - if prevparent = nil then - prevparent := BiffTree.GetLast; - Result := BiffTree.GetLastChild(prevparent); - end; - end; - -begin - if CbFind.Text = '' then - exit; - - s := Lowercase(CbFind.Text); - node0 := BiffTree.FocusedNode; - if node0 = nil then - node0 := BiffTree.GetFirst; - if BiffTree.GetNodeLevel(node0) = 0 then - node0 := BiffTree.GetFirstChild(node0); - - if ANext then begin - if AKeep - then node := node0 - else node := GetNextNode(node0); - repeat - if pos(s, GetRecordname(node)) > 0 then begin - BiffTree.FocusedNode := node; - BiffTree.Selected[node] := true; - BiffTree.ScrollIntoView(node, true); - AddToHistory(GetRecordname(node, false)); - exit; - end; - node := GetNextNode(node); - until (node = node0) or (node = nil); - end else begin - if AKeep - then node := node0 - else node := GetPrevNode(node0); - repeat - if pos(s, GetRecordName(node)) > 0 then begin - BiffTree.FocusedNode := node; - BiffTree.Selected[node] := true; - BiffTree.ScrollIntoView(node, true); - AddToHistory(GetRecordName(node, false)); - exit; - end; - node := GetPrevNode(node); - until (node = node0) or (node = nil); - end; -end; - - -procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: boolean); -begin - if CanClose then - try - WriteToIni; - except - MessageDlg('Could not write setting to configuration file.', mtError, [mbOK], 0); - end; -end; - - -procedure TMainForm.FormCreate(Sender: TObject); -begin - FMRUMenuManager := TMRUMenuManager.Create(self); - with FMRUMenuManager do begin - Name := 'MRUMenuManager'; - IniFileName := GetAppConfigFile(false); - IniSection := 'RecentFiles'; - MaxRecent := 16; - MenuCaptionMask := '&%x - %s'; // & --> create hotkey - MenuItem := MnuFileReopen; - PopupMenu := RecentFilesPopupMenu; - OnRecentFile := @MRUMenuManagerRecentFile; - end; - - HexEditor.Font.Style := []; - - FAnalysisGrid := TBIFFGrid.Create(self); - with FAnalysisGrid do begin - Parent := PgAnalysis; - Align := alClient; - DefaultRowHeight := ValueGrid.DefaultRowHeight; - Options := Options + [goDrawFocusSelected]; - TitleStyle := tsNative; - OnDetails := @AnalysisGridDetails; - OnPrepareCanvas := @AnalysisGridPrepareCanvas; - OnSelection := @AnalysisGridSelection; - TabOrder := 0; - end; - - with ValueGrid do begin - ColCount := 3; - RowCount := VALUE_ROW_PWIDECHAR + 1; - Cells[0, 0] := 'Data type'; - Cells[1, 0] := 'Value'; - Cells[2, 0] := 'Offset range'; - Cells[0, VALUE_ROW_INDEX] := 'Offset'; - Cells[0, VALUE_ROW_BITS] := 'Bits'; - Cells[0, VALUE_ROW_BYTE] := 'Byte'; - Cells[0, VALUE_ROW_SHORTINT] := 'ShortInt'; - Cells[0, VALUE_ROW_WORD] := 'Word'; - Cells[0, VALUE_ROW_SMALLINT] := 'SmallInt'; - Cells[0, VALUE_ROW_DWORD] := 'DWord'; - Cells[0, VALUE_ROW_LONGINT] := 'LongInt'; - Cells[0, VALUE_ROW_QWORD] := 'QWord'; - Cells[0, VALUE_ROW_INT64] := 'Int64'; - Cells[0, VALUE_ROW_SINGLE] := 'Single'; - Cells[0, VALUE_ROW_DOUBLE] := 'Double'; - Cells[0, VALUE_ROW_ANSISTRING] := 'AnsiString'; - Cells[0, VALUE_ROW_PANSICHAR] := 'PAnsiChar'; - Cells[0, VALUE_ROW_WIDESTRING] := 'WideString'; - Cells[0, VALUE_ROW_PWIDECHAR] := 'PWideChar'; - end; - - BiffTree.DefaultNodeHeight := BiffTree.Canvas.TextHeight('Tg') + 4; - BiffTree.Header.DefaultHeight := ValueGrid.DefaultRowHeight; - - UpdateCmds; -end; - - -procedure TMainForm.FormDestroy(Sender: TObject); -begin - if MemStream <> nil then - FreeAndNil(MemStream); - if OLEStorage <> nil then - FreeAndNil(OLEStorage); -end; - - -procedure TMainForm.FormDropFiles(Sender: TObject; - const FileNames: array of String); -begin - LoadFile(FileNames[0]); -end; - - -procedure TMainForm.FormShow(Sender: TObject); -begin - Width := Width + 1; // remove black rectangle next to ValueGrid - Width := Width - 1; -end; - - -function TMainForm.GetBIFFNodeData: PBiffNodeData; -begin - Result := nil; - if BiffTree.FocusedNode <> nil then - begin - Result := BiffTree.GetNodeData(BiffTree.FocusedNode); - if Result <> nil then - MemStream.Position := Result^.Offset; - end; -end; - - -function TMainForm.GetRecType: Word; -var - data: PBiffNodeData; -begin - Result := Word(-1); - if BiffTree.FocusedNode <> nil then - begin - data := BiffTree.GetNodedata(BiffTree.FocusedNode); - if data <> nil then - begin - MemStream.Position := data^.Offset; - Result := WordLEToN(MemStream.ReadWord); - end; - end; -end; - - -function TMainForm.GetValueGridDataSize: Integer; -begin - Result := -1; - case ValueGrid.Row of - VALUE_ROW_BITS : Result := SizeOf(Byte); - VALUE_ROW_BYTE : Result := SizeOf(Byte); - VALUE_ROW_SHORTINT : Result := SizeOf(ShortInt); - VALUE_ROW_WORD : Result := SizeOf(Word); - VALUE_ROW_SMALLINT : Result := SizeOf(SmallInt); - VALUE_ROW_DWORD : Result := SizeOf(DWord); - VALUE_ROW_LONGINT : Result := SizeOf(LongInt); - VALUE_ROW_QWORD : Result := SizeOf(QWord); - VALUE_ROW_INT64 : Result := SizeOf(Int64); - VALUE_ROW_SINGLE : Result := SizeOf(Single); - VALUE_ROW_DOUBLE : Result := SizeOf(Double); - end; -end; - -procedure TMainForm.HexEditorClick(Sender: TObject); -begin - FCurrOffset := HexEditor.SelStart.Index; - PopulateValueGrid; - ValueGridClick(nil); - UpdateStatusbar; -end; - -procedure TMainForm.HexEditorKeyDown(Sender: TObject; var Key: Word; - Shift: TShiftState); -var - sel: TKHexEditorSelection; -begin - case Key of - VK_LEFT : dec(FCurrOffset); - VK_RIGHT : inc(FCurrOffset); - VK_UP : dec(FCurrOffset, HexEditor.LineSize); - VK_DOWN : inc(FCurrOffset, HexEditor.LineSize); - VK_HOME : if (Shift = [ssCtrl]) then - FCurrOffset := 0 else - FCurrOffset := (FCurrOffset div HexEditor.LineSize) * HexEditor.LineSize; - VK_END : if (Shift = [ssCtrl]) then - FCurrOffset := High(FBuffer) else - FCurrOffset := succ(FCurrOffset div HexEditor.LineSize) * HexEditor.lineSize - 1; - VK_NEXT : begin - if (Shift = [ssCtrl]) then - inc(FCurrOffset, HexEditor.LineSize * HexEditor.LineCount) - else - inc(FCurrOffset, HexEditor.LineSize * HexEditor.GetClientHeightChars); - while (FCurrOffset > High(FBuffer)) do - dec(FCurrOffset, HexEditor.LineSize); - end; - VK_PRIOR : if (Shift = [ssCtrl]) then - FCurrOffset := FCurrOffset mod HexEditor.LineSize - else - begin - dec(FCurrOffset, HexEditor.LineSize * HexEditor.GetClientHeightChars); - while (FCurrOffset < 0) do - inc(FCurrOffset, HexEditor.LineSize); - end; - else exit; - end; - if FCurrOffset < 0 then FCurrOffset := 0; - if FCurrOffset > High(FBuffer) then FCurrOffset := High(FBuffer); - sel.Index := FCurrOffset; - sel.Digit := 0; - HexEditor.SelStart := sel; - HexEditorClick(nil); - if not HexEditor.CaretInView then - TMyHexEditor(HexEditor).ScrollTo(HexEditor.SelToPoint(HexEditor.SelStart, HexEditor.EditArea), false, true); - - // Don't process these keys any more! - Key := 0; -end; - -procedure TMainForm.LoadFile(const AFileName: String); -var - valid: Boolean; - excptn: Exception = nil; - ext: String; -begin - if not FileExistsUTF8(AFileName) then begin - MessageDlg(Format('File "%s" not found.', [AFileName]), mtError, [mbOK], 0); - exit; - end; - - ext := Lowercase(ExtractFileExt(AFilename)); - if ext <> '.xls' then begin - MessageDlg('BIFFExplorer can only process binary Excel files (extension ".xls")', - mtError, [mbOK], 0); - exit; - end; - - // .xls files can contain several formats. We look into the header first. - if ext = STR_EXCEL_EXTENSION then - begin - valid := GetFormatFromFileHeader(UTF8ToAnsi(AFileName), FFormat); - // It is possible that valid xls files are not detected correctly. Therefore, - // we open them explicitly by trial and error - see below. - if not valid then - FFormat := sfExcel8; - valid := true; - end else - FFormat := sfExcel8; - - while True do begin - try - LoadFile(AFileName, FFormat); - valid := True; - except - on E: Exception do begin - if FFormat = sfExcel8 then excptn := E; - valid := False - end; - end; - if valid or (FFormat = sfExcel2) then Break; - FFormat := Pred(FFormat); - end; - - // A failed attempt to read a file should bring an exception, so re-raise - // the exception if necessary. We re-raise the exception brought by Excel 8, - // since this is the most common format - if (not valid) and (excptn <> nil) then - raise excptn; -end; - - -procedure TMainForm.LoadFile(const AFileName: String; AFormat: TsSpreadsheetFormat); -var - OLEDocument: TOLEDocument; - streamname: UTF8String; - filestream: TFileStream; -begin - if MemStream <> nil then - FreeAndNil(MemStream); - - if OLEStorage <> nil then - FreeAndNil(OLEStorage); - - MemStream := TMemoryStream.Create; - - if AFormat = sfExcel2 then begin - fileStream := TFileStream.Create(UTF8ToSys(AFileName), fmOpenRead + fmShareDenyNone); - try - MemStream.CopyFrom(fileStream, fileStream.Size); - MemStream.Position := 0; -// MemStream.LoadFromFile(UTF8ToSys(AFileName)); - finally - filestream.Free; - end; - end else begin - OLEStorage := TOLEStorage.Create; - - // Only one stream is necessary for any number of worksheets - OLEDocument.Stream := MemStream; - if AFormat = sfExcel8 then streamname := 'Workbook' else streamname := 'Book'; - OLEStorage.ReadOLEFile(UTF8ToSys(AFileName), OLEDocument, streamname); - - // Check if the operation succeded - if MemStream.Size = 0 then - raise Exception.Create('BIFF Explorer: Reading the OLE document failed'); - end; - - // Rewind the stream and read from it - MemStream.Position := 0; - FFileName := ExpandFileName(AFileName); - ReadFromStream(MemStream); - - FFormat := AFormat; - UpdateCaption; - UpdateStatusbar; - - FMRUMenuManager.AddToRecent(AFileName); -end; - - -procedure TMainForm.ListViewSelectItem(Sender: TObject; Item: TListItem; - Selected: Boolean); -var - n: Word; -begin - if Selected then begin - // Move to start of record + 2 bytes to skip record type ID. - MemStream.Position := PtrInt(Item.Data) + 2; - - // Read size of record - n := WordLEToN(MemStream.ReadWord); - - // Read record data - SetLength(FBuffer, n); - MemStream.ReadBuffer(FBuffer[0], n); - - // Update user interface - Statusbar.Panels[0].Text := Format('Record ID: %s', [Item.SubItems[0]]); - Statusbar.Panels[1].Text := Item.SubItems[1]; - Statusbar.Panels[2].Text := Format('Record size: %s bytes', [Item.SubItems[3]]); - PopulateHexDump; - PageControlChange(nil); - end; -end; - - -procedure TMainForm.MRUMenuManagerRecentFile(Sender: TObject; - const AFileName: string); -begin - LoadFile(AFileName); -end; - - -procedure TMainForm.PopulateAnalysisGrid; -begin - FAnalysisGrid.SetBIFFNodeData(GetBiffNodeData, FBuffer, FFormat); -end; - - -procedure TMainForm.PopulateHexDump; -var - data: TDataSize; -begin - data.Size := Length(FBuffer); - data.Data := @FBuffer[0]; - HexEditor.Clear; - HexEditor.Append(0, data); -end; - - -procedure TMainForm.PopulateValueGrid; -var - buf: array[0..1023] of Byte; - w: word absolute buf; - dw: DWord absolute buf; - qw: QWord absolute buf; - dbl: double absolute buf; - sng: single absolute buf; - idx: Integer; - i, j: Integer; - s: String; - sw: WideString; - ls: Integer; -begin - idx := FCurrOffset; -// idx := HexEditor.SelStart.Index; - - i := ValueGrid.RowCount; - j := ValueGrid.ColCount; - - ValueGrid.Cells[1, VALUE_ROW_INDEX] := IntToStr(idx); - - if idx <= Length(FBuffer)-SizeOf(byte) then begin - ValueGrid.Cells[1, VALUE_ROW_BITS] := IntToBin(FBuffer[idx], 8); - ValueGrid.Cells[2, VALUE_ROW_BITS] := Format('%d ... %d', [idx, idx]); - ValueGrid.Cells[1, VALUE_ROW_BYTE] := IntToStr(FBuffer[idx]); - ValueGrid.Cells[2, VALUE_ROW_BYTE] := ValueGrid.Cells[2, VALUE_ROW_BITS]; - ValueGrid.Cells[1, VALUE_ROW_SHORTINT] := IntToStr(ShortInt(FBuffer[idx])); - ValueGrid.Cells[2, VALUE_ROW_SHORTINT] := ValueGrid.Cells[2, VALUE_ROW_BITS]; - end - else begin - ValueGrid.Cells[1, VALUE_ROW_BYTE] := ''; - ValueGrid.Cells[2, VALUE_ROW_BYTE] := ''; - ValueGrid.Cells[1, VALUE_ROW_SHORTINT] := ''; - ValueGrid.Cells[2, VALUE_ROW_SHORTINT] := ''; - end; - - if idx <= Length(FBuffer)-SizeOf(word) then begin - buf[0] := FBuffer[idx]; - buf[1] := FBuffer[idx+1]; - ValueGrid.Cells[1, VALUE_ROW_WORD] := IntToStr(WordLEToN(w)); - ValueGrid.Cells[2, VALUE_ROW_WORD] := Format('%d ... %d', [idx, idx+SizeOf(Word)-1]); - ValueGrid.Cells[1, VALUE_ROW_SMALLINT] := IntToStr(SmallInt(WordLEToN(w))); - ValueGrid.Cells[2, VALUE_ROW_SMALLINT] := ValueGrid.Cells[2, VALUE_ROW_WORD]; - end else begin - ValueGrid.Cells[1, VALUE_ROW_WORD] := ''; - ValueGrid.Cells[2, VALUE_ROW_WORD] := ''; - ValueGrid.Cells[1, VALUE_ROW_SMALLINT] := ''; - ValueGrid.Cells[2, VALUE_ROW_SMALLINT] := ''; - end; - - if idx <= Length(FBuffer) - SizeOf(DWord) then begin - for i:=0 to SizeOf(DWord)-1 do buf[i] := FBuffer[idx+i]; - ValueGrid.Cells[1, VALUE_ROW_DWORD] := IntToStr(DWordLEToN(dw)); - ValueGrid.Cells[2, VALUE_ROW_DWORD] := Format('%d ... %d', [idx, idx+SizeOf(DWord)-1]); - ValueGrid.Cells[1, VALUE_ROW_LONGINT] := IntToStr(LongInt(DWordLEToN(dw))); - ValueGrid.Cells[2, VALUE_ROW_LONGINT] := ValueGrid.Cells[2, VALUE_ROW_DWORD]; - end else begin - ValueGrid.Cells[1, VALUE_ROW_DWORD] := ''; - ValueGrid.Cells[2, VALUE_ROW_DWORD] := ''; - ValueGrid.Cells[1, VALUE_ROW_LONGINT] := ''; - ValueGrid.Cells[2, VALUE_ROW_LONGINT] := ''; - end; - - if idx <= Length(FBuffer) - SizeOf(QWord) then begin - for i:=0 to SizeOf(QWord)-1 do buf[i] := FBuffer[idx+i]; - ValueGrid.Cells[1, VALUE_ROW_QWORD] := Format('%d', [qw]); - ValueGrid.Cells[2, VALUE_ROW_QWORD] := Format('%d ... %d', [idx, idx+SizeOf(QWord)-1]); - ValueGrid.Cells[1, VALUE_ROW_INT64] := Format('%d', [Int64(qw)]); - ValueGrid.Cells[2, VALUE_ROW_INT64] := ValueGrid.Cells[2, VALUE_ROW_QWORD]; - end else begin - ValueGrid.Cells[1, VALUE_ROW_QWORD] := ''; - ValueGrid.Cells[2, VALUE_ROW_QWORD] := ''; - ValueGrid.Cells[1, VALUE_ROW_INT64] := ''; - ValueGrid.Cells[2, VALUE_ROW_INT64] := ''; - end; - - if idx <= Length(FBuffer) - SizeOf(single) then begin - for i:=0 to SizeOf(single)-1 do buf[i] := FBuffer[idx+i]; - ValueGrid.Cells[1, VALUE_ROW_SINGLE] := Format('%f', [sng]); - ValueGrid.Cells[2, VALUE_ROW_SINGLE] := Format('%d ... %d', [idx, idx+SizeOf(Single)-1]); - end else begin - ValueGrid.Cells[1, VALUE_ROW_SINGLE] := ''; - ValueGrid.Cells[2, VALUE_ROW_SINGLE] := ''; - end; - - if idx <= Length(FBuffer) - SizeOf(double) then begin - for i:=0 to SizeOf(double)-1 do buf[i] := FBuffer[idx+i]; - ValueGrid.Cells[1, VALUE_ROW_DOUBLE] := Format('%f', [dbl]); - ValueGrid.Cells[2, VALUE_ROW_DOUBLE] := Format('%d ... %d', [idx, idx+SizeOf(Double)-1]); - end else begin - ValueGrid.Cells[1, VALUE_ROW_DOUBLE] := ''; - ValueGrid.Cells[2, VALUE_ROW_DOUBLE] := ''; - end; - - if idx < Length(FBuffer) then begin - ls := FBuffer[idx]; - SetLength(s, ls); - i := idx + 1; - j := 0; - while (i < Length(FBuffer)) and (j < Length(s)) do begin - inc(j); - s[j] := char(FBuffer[i]); - inc(i); - end; - SetLength(s, j); - ValueGrid.Cells[1, VALUE_ROW_ANSISTRING] := s; - ValueGrid.Cells[2, VALUE_ROW_ANSISTRING] := Format('%d ... %d', [idx, ls * SizeOf(char) + 1]); - end else begin - ValueGrid.Cells[1, VALUE_ROW_ANSISTRING] := ''; - ValueGrid.Cells[2, VALUE_ROW_ANSISTRING] := ''; - end; - - s := StrPas(PChar(@FBuffer[idx])); - ValueGrid.Cells[1, VALUE_ROW_PANSICHAR] := s; - ValueGrid.Cells[2, VALUE_ROW_PANSICHAR] := Format('%d ... %d', [idx, idx + Length(s)]); - - if idx < Length(FBuffer) then begin - ls := FBuffer[idx]; - SetLength(sw, ls); - j := 0; - i := idx + 2; - while (i < Length(FBuffer)-1) and (j < Length(sw)) do begin - buf[0] := FBuffer[i]; - buf[1] := FBuffer[i+1]; - inc(i, SizeOf(WideChar)); - inc(j); - sw[j] := WideChar(w); - end; - SetLength(sw, j); - ValueGrid.Cells[1, VALUE_ROW_WIDESTRING] := UTF8Encode(sw); - ValueGrid.Cells[2, VALUE_ROW_WIDESTRING] := Format('%d ... %d', [idx, idx + ls*SizeOf(wideChar)+1]); - end else begin - ValueGrid.Cells[1, VALUE_ROW_WIDESTRING] := ''; - ValueGrid.Cells[2, VALUE_ROW_WIDESTRING] := ''; - end; - - s := UTF8Encode(StrPas(PWideChar(@FBuffer[idx]))); - ValueGrid.Cells[1, VALUE_ROW_PWIDECHAR] := s; - ValueGrid.Cells[2, VALUE_ROW_PWIDECHAR] := Format('%d ... %d', [idx, idx + Length(s)]); -end; - - -procedure TMainForm.ReadCmdLine; -begin - if ParamCount > 0 then - LoadFile(ParamStr(1)); -end; - - -procedure TMainForm.ReadFromIni; -var - ini: TCustomIniFile; - i: Integer; -begin - ini := CreateIni; - try - ReadFormFromIni(ini, 'MainForm', self); - - TreePanel.Width := ini.ReadInteger('MainForm', 'RecordList_Width', TreePanel.Width); - for i:=0 to BiffTree.Header.Columns.Count-1 do - BiffTree.Header.Columns[i].Width := ini.ReadInteger('MainForm', - Format('RecordList_ColWidth_%d', [i+1]), BiffTree.Header.Columns[i].Width); - - ValueGrid.Height := ini.ReadInteger('MainForm', 'ValueGrid_Height', ValueGrid.Height); - for i:=0 to ValueGrid.ColCount-1 do - ValueGrid.ColWidths[i] := ini.ReadInteger('MainForm', - Format('ValueGrid_ColWidth_%d', [i+1]), ValueGrid.ColWidths[i]); - - for i:=0 to FAnalysisGrid.ColCount-1 do - FAnalysisGrid.ColWidths[i] := ini.ReadInteger('MainForm', - Format('AnalysisGrid_ColWidth_%d', [i+1]), FAnalysisGrid.ColWidths[i]); - - AnalysisDetails.Height := ini.ReadInteger('MainForm', 'AnalysisDetails_Height', AnalysisDetails.Height); - - HexEditor.AddressMode := TKHexEditorAddressMode(ini.ReadInteger('HexEditor', - 'AddressMode', ord(HexEditor.AddressMode))); - CbHexAddress.Checked := HexEditor.AddressMode = eamHex; - CbHexAddressChange(nil); - - HexEditor.DigitGrouping := ini.ReadInteger('HexEditor', - 'DigitGrouping', HexEditor.DigitGrouping); - CbHexSingleBytes.Checked := HexEditor.DigitGrouping = 1; - CbHexSingleBytesChange(nil); - - HexEditor.LineSize := ini.ReadInteger('HexEditor', - 'LineSize', HexEditor.LineSize); - if HexEditor.LineSize in [10, 16] then - CbHexEditorLineSize.ItemIndex := 0 else CbHexEditorLineSize.ItemIndex := 1; - CbHexEditorLineSizeChange(nil); - - PageControl.ActivePageIndex := ini.ReadInteger('MainForm', 'PageIndex', PageControl.ActivePageIndex); - finally - ini.Free; - end; -end; - - -procedure TMainForm.ReadFromStream(AStream: TStream); -var - recType: Word; - recSize: Word; - p: Cardinal; - p0: Cardinal; - s: String; - i: Integer; - node, prevnode: PVirtualNode; - parentnode: PVirtualNode; - parentdata, data, prevdata: PBiffNodeData; - w: word; - crs: TCursor; -begin - crs := Screen.Cursor; - try - Screen.Cursor := crHourGlass; - BiffTree.Clear; - parentnode := nil; - FXFIndex := -1; - FFontIndex := -1; - FFormatIndex := -1; - FRowIndex := -1; - FExternSheetIndex := 0; // 1-based! - AStream.Position := 0; - while AStream.Position < AStream.Size do begin - p := AStream.Position; - recType := WordLEToN(AStream.ReadWord); - recSize := WordLEToN(AStream.ReadWord); - if (recType = 0) and (recSize = 0) then - break; - s := RecTypeName(recType); - i := pos(':', s); - // in case of BOF record: create new parent node for this substream - if (recType = $0009) or (recType = $0209) or (recType = $0409) or (recType = $0809) - then begin - // Read info on substream beginning here - p0 := AStream.Position; - AStream.Position := AStream.Position + 2; - w := WordLEToN(AStream.ReadWord); - AStream.Position := p0; - // add parent node for this substream - parentnode := BiffTree.AddChild(nil); - // add data to parent node - parentdata := BiffTree.GetNodeData(parentnode); - BiffTree.ValidateNode(parentnode, False); - parentdata^.Offset := p; - parentdata^.RecordName := BOFName(w); - FRowIndex := -1; - end; - // add node to parent node - node := BIFFTree.AddChild(parentnode); - data := BiffTree.GetNodeData(node); - BiffTree.ValidateNode(node, False); - data^.Offset := p; - data^.RecordID := recType; - if i > 0 then begin - data^.RecordName := copy(s, 1, i-1); - data^.RecordDescription := copy(s, i+2, Length(s)); - end else begin - data^.RecordName := s; - data^.RecordDescription := ''; - end; - case recType of - $0008, $0208: // Row - begin - inc(FRowIndex); - data^.Index := FRowIndex; - end; - $0031, $0231: // Font record - begin - inc(FFontIndex); - if FFontIndex > 3 then data^.Index := FFontIndex + 1 - else data^.Index := FFontIndex; - end; - $0043, $00E0: // XF record - begin - inc(FXFIndex); - data^.Index := FXFIndex; - end; - $0017: // EXTERNSHEET record - if FFormat < sfExcel8 then begin - inc(FExternSheetIndex); - data^.Index := FExternSheetIndex; - end; - $001E, $041E: // Format record - begin - inc(FFormatIndex); - data^.Index := FFormatIndex; - end; - $003C: // CONTINUE reocrd - begin - prevnode := BIFFTree.GetPrevious(node); - prevdata := BiffTree.GetNodeData(prevnode); - case prevdata^.RecordID of - $00FC: data^.Tag := BIFFNODE_SST_CONTINUE; // SST record - $01B6: data^.Tag := BIFFNODE_TXO_CONTINUE1; // TX0 record - $003C: begin // CONTINUE record - prevnode := BiffTree.GetPrevious(prevnode); - prevdata := BiffTree.GetNodeData(prevnode); - if prevdata^.RecordID = $01B6 then // TX0 record - data^.Tag := BIFFNODE_TXO_CONTINUE2; - end; - end; - end; - else - data^.Index := -1; - end; - - // advance stream pointer - AStream.Position := AStream.Position + recSize; - end; - - // expand all parent nodes - node := BiffTree.GetFirst; - while node <> nil do begin - BiffTree.Expanded[node] := true; - node := BiffTree.GetNextSibling(node); - end; - // Select first node - BiffTree.FocusedNode := BiffTree.GetFirst; - BiffTree.Selected[BiffTree.FocusedNode] := true; - - UpdateCmds; - - finally - Screen.Cursor := crs; - end; -end; - - -procedure TMainForm.PageControlChange(Sender: TObject); -var - sel: TKHexEditorSelection; - i, n: Integer; - s: String; -begin - if (BiffTree.FocusedNode = nil) or - (BiffTree.FocusedNode^.Parent = BiffTree.RootNode) - then - exit; - - PopulateAnalysisGrid; - for i:=1 to FAnalysisGrid.RowCount-1 do begin - s := FAnalysisGrid.Cells[0, i]; - if s = '' then break; - n := StrToInt(s); - if (n >= FCurrOffset) then - begin - FAnalysisGrid.Row := IfThen(n = FCurrOffset, i, i-1); - break; - end; - end; - - sel.Index := FCurrOffset; - sel.Digit := 0; - HexEditor.SelStart := sel; - PopulateValueGrid; - ValueGridClick(nil); -{ - if PageControl.ActivePage = PgAnalysis then - PopulateAnalysisGrid - else - if PageControl.ActivePage = PgValues then - begin - sel.Index := FCurrOffset; - sel.Digit := 0; - HexEditor.SelStart := sel; - PopulateValueGrid; - ValueGridClick(nil); - end;} -end; - - -procedure TMainForm.UpdateCaption; -begin - if FFileName = '' then - Caption := 'BIFF Explorer - (no file loaded)' - else - Caption := Format('BIFF Explorer - "%s [%s]', [ - FFileName, - GetFileFormatName(FFormat) - ]); -end; - - -procedure TMainForm.UpdateCmds; -begin - AcDumpToFile.Enabled := FFileName <> ''; - AcFind.Enabled := FFileName <> ''; -end; - - -procedure TMainForm.UpdateStatusbar; -begin - if FCurrOffset > -1 then - Statusbar.Panels[3].Text := Format('HexViewer offset: %d', [FCurrOffset]) - else - Statusbar.Panels[3].Text := ''; -end; - - -procedure TMainForm.ValueGridClick(Sender: TObject); -var - sel: TKHexEditorSelection; - n: Integer; -begin - sel := HexEditor.SelStart; - - n := GetValueGridDataSize; - if n > 0 then begin - sel.Digit := 0; - HexEditor.SelStart := sel; - inc(sel.Index, n-1); - sel.Digit := 1; - HexEditor.SelEnd := sel; - end else - HexEditor.SelEnd := sel; -end; - - -procedure TMainForm.ValueGridPrepareCanvas(sender: TObject; aCol, - aRow: Integer; aState: TGridDrawState); -begin - if ARow = 0 then ValueGrid.Canvas.Font.Style := [fsBold]; -end; - - -procedure TMainForm.WriteToIni; -var - ini: TCustomIniFile; - i: Integer; -begin - ini := CreateIni; - try - WriteFormToIni(ini, 'MainForm', self); - - ini.WriteInteger('MainForm', 'RecordList_Width', TreePanel.Width); - for i:=0 to BiffTree.Header.Columns.Count-1 do - ini.WriteInteger('MainForm', Format('RecordList_ColWidth_%d', [i+1]), BiffTree.Header.Columns[i].Width); - - ini.WriteInteger('MainForm', 'ValueGrid_Height', ValueGrid.Height); - for i:=0 to ValueGrid.ColCount-1 do - ini.WriteInteger('MainForm', Format('ValueGrid_ColWidth_%d', [i+1]), ValueGrid.ColWidths[i]); - - for i:=0 to FAnalysisGrid.ColCount-1 do - ini.WriteInteger('MainForm', Format('AnalysisGrid_ColWidth_%d', [i+1]), FAnalysisGrid.ColWidths[i]); - - ini.WriteInteger('MainForm', 'AnalysisDetails_Height', AnalysisDetails.Height); - - ini.WriteInteger('MainForm', 'PageIndex', PageControl.ActivePageIndex); - - ini.WriteInteger('HexEditor', 'AddressMode', ord(HexEditor.AddressMode)); - ini.WriteInteger('HexEditor', 'DigitGrouping', HexEditor.DigitGrouping); - ini.WriteInteger('HexEditor', 'LineSize', HexEditor.LineSize); - - finally - ini.Free; - end; -end; - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/betypes.pas b/components/fpspreadsheet/reference/BIFFExplorer/betypes.pas deleted file mode 100644 index f7c42631e..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/betypes.pas +++ /dev/null @@ -1,30 +0,0 @@ -unit beTypes; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils; - -const - BIFFNODE_TXO_CONTINUE1 = 1; - BIFFNODE_TXO_CONTINUE2 = 2; - BIFFNODE_SST_CONTINUE = 3; - -type - { Virtual tree node data } - TBiffNodeData = record //class - Offset: Integer; - RecordID: Integer; - RecordName: String; - RecordDescription: String; - Index: Integer; - Tag: Integer; - end; - PBiffNodeData = ^TBiffNodeData; - -implementation - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/beutils.pas b/components/fpspreadsheet/reference/BIFFExplorer/beutils.pas deleted file mode 100644 index 79362d95b..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/beutils.pas +++ /dev/null @@ -1,165 +0,0 @@ -unit beUtils; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, IniFiles, Forms, - fpstypes, fpspreadsheet; - -function CreateIni : TCustomIniFile; -procedure ReadFormFromIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm); -procedure WriteFormToIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm); - -function GetFileFormatName(AFormat: TsSpreadsheetFormat): String; -function GetFormatFromFileHeader(const AFileName: TFileName; - out SheetType: TsSpreadsheetFormat): Boolean; - - -implementation - -uses - uvirtuallayer_ole; - -function CreateIni : TCustomIniFile; -var - cfg : string; -begin - cfg := GetAppConfigDir(false); - if not DirectoryExists(cfg) then - CreateDir(cfg); - result := TMemIniFile.Create(GetAppConfigFile(false)); -end; - -procedure ReadFormFromIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm); -var - L,T,W,H: Integer; - isMax: Boolean; -begin - L := ini.ReadInteger(ASection, 'Left', AForm.Left); - T := Ini.ReadInteger(ASection, 'Top', AForm.Top); - W := ini.ReadInteger(ASection, 'Width', AForm.Width); - H := ini.ReadInteger(ASection, 'Height', AForm.Height); - isMax := ini.ReadBool(ASection, 'Maximized', AForm.WindowState = wsMaximized); - if W > Screen.Width then W := Screen.Width; - if H > Screen.Height then H := Screen.Height; - if L < 0 then L := 0; - if T < 0 then T := 0; - if L + W > Screen.Width then L := Screen.Width - W; - if T + H > Screen.Height then T := Screen.Height - H; - AForm.Left := L; - AForm.Top := T; - AForm.Width := W; - AForm.Height := H; - if IsMax then - AForm.WindowState := wsMaximized - else - AForm.WindowState := wsNormal; -end; - - -procedure WriteFormToIni(ini: TCustomIniFile; ASection: String; AForm: TCustomForm); -begin - ini.WriteBool(ASection, 'Maximized', (AForm.WindowState = wsMaximized)); - if AForm.WindowState = wsNormal then begin - ini.WriteInteger(ASection, 'Left', AForm.Left); - ini.WriteInteger(ASection, 'Top', AForm.Top); - ini.WriteInteger(ASection, 'Width', AForm.Width); - ini.WriteInteger(ASection, 'Height', AForm.Height); - end; -end; - -function GetFileFormatName(AFormat: TsSpreadsheetFormat): string; -begin - case AFormat of - sfExcel2 : Result := 'BIFF2'; - { Excel3/4 not supported fpspreadsheet - sfExcel3 : Result := 'BIFF3'; - sfExcel4 : Result := 'BIFF4'; - } - sfExcel5 : Result := 'BIFF5'; - sfExcel8 : Result := 'BIFF8'; - sfooxml : Result := 'OOXML'; - sfOpenDocument : Result := 'Open Document'; - sfCSV : Result := 'CSV'; - sfWikiTable_Pipes : Result := 'WikiTable Pipes'; - sfWikiTable_WikiMedia : Result := 'WikiTable WikiMedia'; - else Result := '-unknown format-'; - end; -end; - -function GetFormatFromFileHeader(const AFileName: TFileName; - out SheetType: TsSpreadsheetFormat): Boolean; -const - BIFF2_HEADER: array[0..3] of byte = ( - $09,$00, $04,$00); // they are common to all BIFF2 files that I've seen - BIFF58_HEADER: array[0..7] of byte = ( - $D0,$CF, $11,$E0, $A1,$B1, $1A,$E1); - - function ValidOLEStream(AStream: TStream; AName: String): Boolean; - var - fsOLE: TVirtualLayer_OLE; - begin - AStream.Position := 0; - fsOLE := TVirtualLayer_OLE.Create(AStream); - try - fsOLE.Initialize; - Result := fsOLE.FileExists('/'+AName); - finally - fsOLE.Free; - end; - end; - -var - buf: packed array[0..7] of byte = (0,0,0,0,0,0,0,0); - stream: TStream; - i: Integer; - ok: Boolean; -begin - Result := false; - stream := TFileStream.Create(AFileName, fmOpenRead + fmShareDenyNone); - try - // Read first 8 bytes - stream.ReadBuffer(buf, 8); - - // Check for Excel 2 - ok := true; - for i:=0 to High(BIFF2_HEADER) do - if buf[i] <> BIFF2_HEADER[i] then - begin - ok := false; - break; - end; - if ok then - begin - SheetType := sfExcel2; - Exit(True); - end; - - // Check for Excel 5 or 8 - for i:=0 to High(BIFF58_HEADER) do - if buf[i] <> BIFF58_HEADER[i] then - exit; - - // Now we know that the file is a Microsoft compound document. - - // We check for Excel 5 in which the stream is named "Book" - if ValidOLEStream(stream, 'Book') then begin - SheetType := sfExcel5; - exit(True); - end; - - // Now we check for Excel 8 which names the stream "Workbook" - if ValidOLEStream(stream, 'Workbook') then begin - SheetType := sfExcel8; - exit(True); - end; - - finally - stream.Free; - end; -end; - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/mrumanager.pp b/components/fpspreadsheet/reference/BIFFExplorer/mrumanager.pp deleted file mode 100644 index 847f886e9..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/mrumanager.pp +++ /dev/null @@ -1,485 +0,0 @@ -{ MRU (Most Recent Used) menu item manager - - Copyright (C) 2011 Michael Van Canneyt (michael@freepascal.org) - Modifications by Werner Pamler - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version with the following modification: - - As a special exception, the copyright holders of this library give you - permission to link this library with independent modules to produce an - executable, regardless of the license terms of these independent modules,and - to copy and distribute the resulting executable under terms of your choice, - provided that you also meet, for each linked independent module, the terms - and conditions of the license of that module. An independent module is a - module which is not derived from or based on this library. If you modify - this library, you may extend this exception to your version of the library, - but you are not obligated to do so. If you do not wish to do so, delete this - exception statement from your version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License - for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - modified by wp -} -unit mrumanager; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, inifiles, menus; - -Type - { TRecentMenuItem } - - TRecentMenuItem = Class(TMenuItem) - Private - FFileName : string; - Public - Property FileName : String Read FFileName; - end; - TRecentMenuItemClass = Class of TRecentMenuItem; - - { TMRUMenuManager } - - TOnRecentFileEvent = Procedure(Sender : TObject; Const AFileName : String) of object; - - TMRUMenuManager = Class(TComponent) - Private - FIniFileName: String; - FIniSection: String; - FOnRecent: TOnRecentFileEvent; - FRecent : TStrings; - FMaxRecent : Integer; - FMenuCaptionMask : string; - FMIRecent : TMenuItem; - FPMRecent : TPopupMenu; - FMaxItemLength : integer; - procedure SetIniFileName(const AValue:string); - procedure SetIniSection(const AValue:string); - procedure SetMaxItemLength(const AValue:integer); - procedure SetMenuCaptionMask(const AValue:string); - procedure SetMIRecent(const AValue: TMenuItem); - procedure SetPMRecent(const AValue: TPopupMenu); - procedure SetRecent(const AValue: TStrings); - protected - // Overrides. - procedure Loaded; override; - procedure Notification(AComponent: TComponent; Operation: TOperation); override; - // Return default name and section if either is empty. - procedure GetFileNameAndSection(Var AFileName,ASection : String); virtual; - // Override if you want to load additional values. - procedure LoadFromIni(Ini: TCustomIniFile; ASection: String); virtual; - // Override if you want to write additional values. - procedure SaveToIni(Ini: TCustomIniFile; ASection: String); virtual; - // Called when menu item is clicked. - procedure DoOnRecentClick(Sender: TObject); virtual; - // Override this if you want to create a custom class of menu itel. - function CreateMenuItem(AOwner: TComponent): TRecentMenuItem; virtual; - // Create a menu caption. Default is index followed by filename. - // Override if you want to customize. - Function CreateMenuCaption(AIndex : Integer; Const AFileName : String) : String; virtual; - Public - Constructor Create(AOwner : TComponent);override; - Destructor Destroy; override; - // Load files from ini file AFileName in section ASection. Calls ShowRecentFiles - // Need for explicit call only when IniFileName='' and IniSection='' and class created at run-time - procedure LoadRecentFilesFromIni(const AFileName: string=''; const ASection: String=''); - // Saves files to ini file AFileName in section ASection. - procedure SaveRecentFilesToIni(const AFileName: string=''; const ASection: String=''); - // Add a filename to the list of files. - // If an existing file is added, it is moved first in the list. - // If MaxRecent is attained, the last one is removed. - // Calls ShowRecentFiles. - procedure AddToRecent(AFileName: String); - // Re-populate the menu. - procedure ShowRecentFiles; - Published - // Max. items to be kept in the list. - Property MaxRecent : Integer Read FMaxRecent write FMaxRecent; - // Menu item to create a submenu under. Existing items will be removed. - Property MenuItem : TMenuItem Read FMIRecent Write SetMIRecent; - // Popupmenu attached to a toolbar button. Existing items will be removed. - Property PopupMenu : TPopupMenu Read FPMRecent Write SetPMRecent; - // Default ini filename. - Property IniFileName : String Read FIniFileName Write SetIniFileName; - // Default ini section. - Property IniSection : String Read FIniSection Write SetIniSection; - // Maximum length of recent menu item - Property MaxItemLength : integer Read FMaxItemLength Write SetMaxItemLength default 80; - // Format mask for MenuCaption: first placeholder must be %d, second %s, e.g. '%d - %s' - Property MenuCaptionMask : string read FMenuCaptionMask Write SetMenuCaptionMask; - // Recent items. If adding manually to the list, ShowRecentFiles must be called manually. - Property Recent : TStrings Read FRecent Write SetRecent; - // Called when the user clicks an recent meu item. - Property OnRecentFile : TOnRecentFileEvent Read FOnRecent Write FOnRecent; - end; - EMRUManager = Class(Exception); - -Const - DefaultIniFile = 'recent.ini'; - DefaultSection = 'Global'; - KeyMaxRecent = 'MaxRecent'; - KeyCount = 'Count'; - KeyFile = 'File%d'; - -implementation - -Resourcestring - SErrFailedToCreateDir = 'Failed to create directory "%s"'; - -const - DEFAULT_MASK = '%d. %s'; - -function MinimizeFileName(const AFileName:string; AMaxLen:integer) : string; - - procedure SplitPath(const APath:String; Parts: TStrings); - { Splits the provided path into constituent folder names } - var - i, j : Integer; - begin - if APath = '' then exit; - if not Assigned(Parts) then exit; - - i := Length(APath); - j := i; - while (i >= 1) do begin - if APath[i] = DirectorySeparator then begin - Parts.Insert(0, copy(APath, i+1, j-i)); - j := i; - end; - dec(i); - end; - Parts.Insert(0, copy(APath, 1, j)); - end; - - function AddStringsFromTo(AList:TStrings; FromIndex,ToIndex:integer) : string; - var - i : integer; - begin - result := ''; - for i:=FromIndex to ToIndex do - result := result + AList[i]; - end; - -var - Parts : TStringList; - i : integer; - tmp : string; -begin - result := AFileName; - if Length(AFileName) > AMaxLen then begin - Parts := TStringList.Create; - try - SplitPath(AFileName, Parts); - i := Parts.Count div 2; - while (i < Parts.Count) do begin - tmp := Format('%s...%s%s', [ - AddStringsFromTo(Parts, 0, i-1), - DirectorySeparator, - AddStringsFromTo(Parts, i+1, Parts.Count-1) - ]); - if Length(tmp) < AMaxLen then begin - result := tmp; - exit; - end else - Parts.Delete(i); - i := Parts.Count div 2; - end; - result := ExtractFileName(AFileName); - finally - Parts.Free; - end; - end; -end; - -procedure TMRUMenuManager.AddToRecent(AFileName : String); - -Var - I,J : Integer; - B : Boolean; - -begin - AFileName:=ExpandFileName(AFileName); - With FRecent do - begin - J:=IndexOf(AFileName); - If (J<>-1) then - begin - if (J>0) then - Exchange(0,J) - end - else - begin - While (Count>=FMaxRecent) do - Delete(Count-1); - Insert(0,AFileName) - end; - end; - ShowRecentFiles; -end; - -function TMRUMenuManager.CreateMenuItem(AOwner :TComponent) : TRecentMenuItem; - -begin - Result:=TRecentMenuItem.Create(AOwner); -end; - -function TMRUMenuManager.CreateMenuCaption(AIndex: Integer; - const AFileName: String): String; -var - fn : string; - mask : string; -begin - if FMaxItemLength > 0 then - fn := MinimizeFileName(AFileName, FMaxItemLength) - else - fn := AFileName; - if FMenuCaptionMask = '' then - mask := DEFAULT_MASK - else - mask := FMenuCaptionMask; - Result:=Format(mask, [AIndex+1,fn]); -end; - -procedure TMRUMenuManager.ShowRecentFiles; - -Var - I : Integer; - M : TRecentMenuItem; - -begin - if Assigned(FMIRecent) then begin - FMIRecent.clear; - For I:=0 to FRecent.Count-1 do - begin - M:=CreateMenuItem(Self.Owner); - M.Caption:=CreateMenuCaption(I,FRecent[i]); - M.FFileName:=FRecent[i]; - M.OnClick:=@DoOnRecentClick; - FMIRecent.Add(M); - end; - end; - if Assigned(FPMRecent) then begin - FPMRecent.Items.Clear; - for i:=0 to FRecent.Count-1 do - begin - M := CreateMenuItem(Self.Owner); - M.Caption := CreateMenuCaption(I, Recent[i]); - M.FFileName := FRecent[i]; - M.OnClick := @DoOnRecentClick; - FPMRecent.Items.Add(M); - end; - end; -end; - -procedure TMRUMenuManager.LoadFromIni(Ini : TCustomIniFile; ASection : String); - -Var - I,Count : Integer; - FN : String; - -begin - FRecent.Clear; - FMaxRecent:=Ini.ReadInteger(ASection,KeyMaxRecent,10); - Count:=Ini.ReadInteger(ASection,KeyCount,0); - For I:=1 to Count do - begin - FN:=Ini.ReadString(ASection,Format(KeyFile,[i]),''); - If (FN<>'') then - FRecent.Add(FN); - end; -end; - -procedure TMRUMenuManager.GetFileNameAndSection(var AFileName, ASection: String); - -begin - if (AFileName='') then - begin - AFileName:=GetAppConfigDir(False); - AFileName:=IncludeTrailingPathDelimiter(AFileName)+DefaultIniFile; - end; - if (ASection='') then - ASection:=DefaultSection; -end; - -procedure TMRUMenuManager.LoadRecentFilesFromIni(Const AFileName : string = ''; Const ASection : String = ''); - -Var - DN,FN,Sec : String; - Ini : TIniFile; - -begin - FN:=AFileName; - Sec:=ASection; - GetFileNameAndSection(FN,Sec); - DN:=ExtractFilePath(FN); - If ForceDirectories(DN) then - begin - If FileExists(FN) then - begin - Ini:=TIniFile.Create(FN); - try - LoadFromIni(Ini,Sec); - finally - Ini.Free; - end; - end; - end; - ShowRecentFiles; -end; - -procedure TMRUMenuManager.SaveToIni(Ini : TCustomIniFile; ASection : String); - -Var - I : Integer; -begin - Ini.EraseSection(ASection); - Ini.WriteInteger(ASection,KeyMaxRecent,FMaxRecent); - Ini.WriteInteger(ASection,KeyCount,FRecent.Count); - For I:=0 to FRecent.Count-1 do - Ini.WriteString(ASection,Format(KeyFile,[i+1]),FRecent[i]); - Ini.UpdateFile; -end; - -procedure TMRUMenuManager.SaveRecentFilesToIni(Const AFileName : string = ''; Const ASection : String = ''); - -Var - DN,FN,Sec : String; - Ini : TMemIniFile; - -begin - FN:=AFileName; - Sec:=ASection; - GetFileNameAndSection(FN,Sec); - DN:=ExtractFilePath(FN); - If not ForceDirectories(DN) then - Raise EMRUManager.CreateFmt(SErrFailedToCreateDir,[DN]); - Ini:=TMemIniFile.Create(FN); - try - SaveToIni(Ini,Sec); - finally - Ini.Free; - end; -end; - -procedure TMRUMenuManager.SetIniFileName(const AValue:string); -begin - if AValue <> FIniFileName then begin - FIniFileName := AValue; - LoadRecentFilesFromIni(FIniFileName, FIniSection); - end; -end; - -procedure TMRUMenuManager.SetIniSection(const AValue:string); -begin - if AValue <> FIniSection then begin - FIniSection := AValue; - LoadRecentFilesFromini(FIniFileName, FIniSection); - end; -end; - -procedure TMRUMenuManager.SetMaxItemLength(const AValue:integer); -begin - if FMaxItemLength <> AValue then begin - FMaxItemLength := AValue; - ShowRecentFiles; - end; -end; - -procedure TMRUMenuManager.SetMenuCaptionMask(const AValue:string); -begin - if FMenuCaptionMask <> AValue then begin - FMenuCaptionMask := AValue; - ShowRecentFiles; - end; -end; - -procedure TMRUMenuManager.SetMIRecent(const AValue: TMenuItem); -begin - if FMIRecent=AValue then exit; - If Assigned(FMIRecent) then - FMIRecent.RemoveFreeNotification(Self); - FMIRecent:=AValue; - If Assigned(FMIRecent) then - FMIRecent.FreeNotification(Self); - ShowRecentFiles; -end; - -procedure TMRUMenuManager.SetPMRecent(const AValue: TPopupMenu); -begin - if FPMRecent=AValue then exit; - if Assigned(FPMRecent) then - FPMRecent.RemoveFreeNotification(self); - FPMRecent := AValue; - if Assigned(FPMRecent) then - FPMRecent.FreeNotification(self); - ShowRecentFiles; -end; - -procedure TMRUMenuManager.SetRecent(const AValue: TStrings); -begin - if FRecent=AValue then exit; - FRecent.Assign(AValue); - ShowRecentFiles; -end; - -procedure TMRUMenuManager.loaded; -begin - inherited loaded; - if (FRecent.Count>0) and (assigned(FMIRecent) or assigned(FPMRecent))then - LoadRecentFilesFromIni(FIniFileName, FIniSection); -end; - -constructor TMRUMenuManager.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FRecent:=TStringList.Create; - FMaxItemLength := 80; - FMenuCaptionMask := DEFAULT_MASK; -end; - -destructor TMRUMenuManager.Destroy; -begin - SaveRecentFilesToIni(FIniFileName, FIniSection); - FreeAndNil(FRecent); - inherited Destroy; -end; - -procedure TMRUMenuManager.Notification(AComponent: TComponent; - Operation: TOperation); -begin - inherited Notification(AComponent, Operation); - if (Operation = opRemove) then begin - if AComponent = FMIRecent then FMIRecent := nil; - if AComponent = FPMRecent then FPMRecent := nil; - end; - { original code - I think this is not correct: - inherited Notification(AComponent, Operation); - if (Operation=opRemove) and ((AComponent=FMIRecent) or (AComponent=FPMRecent)) then - exit; - } -end; - -procedure TMRUMenuManager.DoOnRecentClick(Sender: TObject); -Var - FN : String; -begin - With (Sender as TRecentMenuItem) do - FN:=FileName; - if (FN<>'') and (OnRecentFile<>Nil) then - OnRecentFile(Self,FN); -end; - -end. - diff --git a/components/fpspreadsheet/reference/BIFFExplorer/readme.txt b/components/fpspreadsheet/reference/BIFFExplorer/readme.txt deleted file mode 100644 index 375ddcdfc..000000000 --- a/components/fpspreadsheet/reference/BIFFExplorer/readme.txt +++ /dev/null @@ -1,20 +0,0 @@ -BIFF Explorer --------------------------------------------------------------------------------- - -"BIFF Explorer" is a tool to peek into the internal structure of a binary -Excel file in biff format. - -It displays a list of the BIFF records contained in the xls file along with -name and explanation as described in various documentation files (see "About"). -Selecting one of the records loads its bytes into a simple hex viewer; for the -most important records I tried to decipher the contents of the hex values and -display their meaning in a grid and a memo (page "Analysis"). For the other -records select a byte in the hex viewer, and the program will display the -contents of that byte and the following ones as integer, double, string -(page "Values"). - -For compiling, note that the program requires the following packages -from ccr -- "KControls" -- "lclextensions" -- "VirtualTreeview-new"