⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uescherrecords.pas

📁 TMS component pack v4.2 for delphi
💻 PAS
📖 第 1 页 / 共 4 页
字号:
  ERec.Id:=Id;
  ERec.Pre:=Pre;
  ERec.Size:=TotalDataSize;

  Result:= ClassOfTEscherRecord(ClassType).Create(ERec, DwgGroupCache, NewDwgCache, Nil);
  CopiedTo:=Result;
  Result.LoadedDataSize:=LoadedDataSize;
  if FParent<> nil then
    if FParent.CopiedTo<>nil then Result.FParent:= FParent.CopiedTo as TEscherContainerRecord
    else Result.FParent:=FParent
  else Result.FParent:=nil;
end;

function TEscherRecord.IsContainer(const aPre: word): boolean;
begin
  IsContainer:=(aPre and $000F ) = $000F
end;

function TEscherRecord.Loaded: boolean;
begin
  if LoadedDataSize>TotalDataSize then Raise Exception.Create(ErrInternal);
  Loaded:= TotalDataSize=LoadedDataSize;
end;

procedure TEscherRecord.WriteNewRecord(const DataStream: TStream; const BreakList: TBreakList);
var
 Rh: TRecordHeader;
begin
  Rh.Id:= BreakList.CurrentId;
  Rh.Size:= BreakList.CurrentSize;
  if DataStream.Write(Rh, SizeOf(Rh)) <> Sizeof(Rh) then raise Exception.Create(ErrCantWrite);
end;

procedure TEscherRecord.IncNextPos(var NextPos: integer; const Size: integer;var RealSize:integer; const BreakList: TBreakList);
begin
  if NextPos> MaxRecordDataSize+1 then Raise Exception.Create(ErrInternal);
  inc(NextPos, Size);
  inc(RealSize, Size);
  while NextPos>MaxRecordDataSize+1 do
  begin
    dec(NextPos, MaxRecordDataSize+1);
    inc(RealSize, SizeOf(TRecordHeader));  //continue record
    if BreakList<>nil then BreakList.Add(xlr_CONTINUE, MaxRecordDataSize+1);
  end;
end;

procedure TEscherRecord.SplitRecords(var NextPos, RealSize: integer; var NextDwg: integer; const BreakList: TBreakList);
begin
  if NextDwg>0 then
  begin
    if BreakList<>nil then BreakList.Add(NextDwg, NextPos);
    Inc(RealSize, SizeOf(TRecordHeader));
    NextPos:=0;
    NextDwg:=-1;
  end;

  IncNextPos(NextPos, SizeOf(TEscherRecordHeader), RealSize, BreakList);
end;

procedure TEscherRecord.CheckSplit(const DataStream: TStream; const BreakList: TBreakList);
begin
  if (DataStream.Position > BreakList.AcumSize) then Raise Exception.Create(ErrInternal);
  if DataStream.Position = BreakList.AcumSize then
  begin
    WriteNewRecord(DataStream, BreakList);
    BreakList.IncCurrent;
  end;
end;

procedure TEscherRecord.SaveToStream(const DataStream: TStream; const BreakList: TBreakList);
var
  Remaining:integer;
  Rs: TEscherRecordHeader;
begin
  if not Loaded then raise Exception.Create(ErrEscherNotLoaded);

  Rs.Pre:= Pre;
  Rs.Id:=Id;
  Rs.Size:=TotalSizeNoSplit-SizeOf(TEscherRecordHeader);
  CheckSplit(DataStream, BreakList);
  Remaining:= (BreakList.AcumSize - DataStream.Position) ;
  if SizeOf(Rs)>Remaining then
  begin
    if DataStream.Write(Rs, Remaining) <> Remaining then raise Exception.Create(ErrCantWrite);
    CheckSplit(DataStream, BreakList);
    if DataStream.Write((PCHAR(@Rs)+Remaining)^, Sizeof(Rs)-Remaining) <> Sizeof(Rs)-Remaining then raise Exception.Create(ErrCantWrite);
  end
  else if DataStream.Write(Rs, Sizeof(Rs)) <> Sizeof(Rs) then raise Exception.Create(ErrCantWrite);
end;

function TEscherRecord.TotalSizeNoSplit: int64;
begin
  Result:=SizeOf(TEscherRecordHeader);
end;

function TEscherRecord.WaitingClientData(var ClientType: ClassOfTBaseClientData): boolean;
begin
  Result:=false;
  ClientType:=nil;
end;

function TEscherRecord.Instance: word;
begin
  Result:= Pre shr 4;
end;

function TEscherRecord.Version: word;
begin
  Result:= Pre and $F;
end;


function TEscherRecord.FindRoot: TEscherRecord;
begin
  Result:=Self;
  if DwgCache=nil then exit;
  while (Result<>nil)and (Result.FParent<>DwgCache.Patriarch) do Result:=Result.FParent;
end;

function TEscherRecord.CopyDwg(const RowOfs, ColOfs: integer): TEscherRecord;
begin
  if ((DwgCache.Patriarch=nil) or (FindRoot=nil)) then raise Exception.Create(ErrLoadingEscher);
  DwgCache.Patriarch.FContainedRecords.Add(FindRoot.CopyTo(DwgCache, RowOfs, ColOfs));
  Result:=CopiedTo;
end;

function TEscherRecord.Patriarch: TEscherSpgrContainerRecord;
begin
  if (DwgCache=nil) then Result:=nil else
  Result:=DwgCache.Patriarch;
end;

function TEscherRecord.CompareRec(const aRecord: TEscherRecord): integer;
begin
  if Id< aRecord.Id then Result:=-1 else if aRecord.Id>Id then Result:=1 else
  if Pre<aRecord.Pre then result:=-1 else if Pre>aRecord.Pre then Result:=1 else
  if TotalDataSize< aRecord.TotalDataSize then Result:=-1 else if TotalDataSize> aRecord.TotalDataSize then Result:=1 else
  Result:=0;
end;

procedure TEscherRecord.AfterCreate;
begin
  //nothing
end;

function TEscherRecord.FindRec(const RecClass: ClassOfTEscherRecord): TEscherRecord;
begin
  Result:=nil;
end;

{ TEscherRecordList }

function TEscherRecordList.TotalSizeNoSplit: int64;
var
  i: integer;
begin
  Result:=0;
  for i:=0 to Count-1 do Result:=Result+Items[i].TotalSizeNoSplit;
end;

{$INCLUDE TEscherRecordListImp.inc}

procedure TEscherRecordList.SaveToStream(const DataStream: TStream; const BreakList: TBreakList);
var
  i:integer;
begin
  for i:=0 to Count-1 do if Items[i]<>nil then Items[i].SaveToStream(DataStream, BreakList);
end;

procedure TEscherRecordList.CopyFrom(const aEscherRecordList: TEscherRecordList; const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer);
var
  i:integer;
begin
  if aEscherRecordList=nil then exit;
  for i:=0 to aEscherRecordList.Count-1 do Add(aEscherRecordList[i].CopyTo(NewDwgCache, RowOfs, ColOfs));
end;

{ TEscherDataRecord }

procedure TEscherDataRecord.ClearData;
begin
  FillChar(Data^, TotalDataSize, 0);
end;

function TEscherDataRecord.CompareRec(const aRecord: TEscherRecord): integer;
var
  i:integer;
begin
  Result:=inherited CompareRec(aRecord);
  if Result=0 then
  begin
    for i:=0 to TotalDataSize-1 do if Data[i]<(aRecord as TEscherDataRecord).Data[i] then begin Result:=-1; exit;end else
                                   if Data[i]>(aRecord as TEscherDataRecord).Data[i] then begin Result:=1; exit; end;
  end;
end;

constructor TEscherDataRecord.Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  inherited;
  GetMem(Data, TotalDataSize);
end;

destructor TEscherDataRecord.Destroy;
begin
  FreeMem(Data);
  inherited;
end;

function TEscherDataRecord.DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord;
begin
  Result:=inherited DoCopyTo(NewDwgCache, RowOfs, ColOfs);
  Move(Data^, (Result as TEscherDataRecord).Data^, TotalDataSize);
end;

procedure TEscherDataRecord.Load(var aRecord: TBaseRecord; var aPos: integer);
var
  RSize: integer;
begin
  if TotalDataSize=0 then exit;
  RSize:=aRecord.TotalSizeNoHeaders-aPos;
  if RSize<=0 then raise Exception.Create(ErrLoadingEscher);
  if TotalDataSize - LoadedDataSize < RSize  then RSize:=TotalDataSize - LoadedDataSize;
  if LoadedDataSize+RSize> TotalDataSize then raise Exception.Create(ErrLoadingEscher);
  ReadMem(aRecord, aPos, RSize, PChar(Data)+ LoadedDataSize);
  inc(LoadedDataSize, RSize);
end;

procedure TEscherDataRecord.SaveToStream(const DataStream: TStream; const BreakList: TBreakList);
var
  RemainingSize: integer;
  FracSize: integer;
begin
  inherited;
  if TotalDataSize > 0 then
  begin
    RemainingSize:= TotalDataSize;
    while RemainingSize> BreakList.AcumSize - DataStream.Position do
    begin
      FracSize:= BreakList.AcumSize - DataStream.Position;
      CheckSplit(DataStream, BreakList);
      if DataStream.Write((PCHAR(Data)+ TotalDataSize-RemainingSize)^, FracSize) <> FracSize then
        raise Exception.Create(ErrCantWrite);

      dec(RemainingSize, FracSize);
    end; //while

    CheckSplit(DataStream, BreakList);
    if DataStream.Write((PCHAR(Data)+ TotalDataSize-RemainingSize)^, RemainingSize) <> RemainingSize then
      raise Exception.Create(ErrCantWrite);

  end;
end;

procedure TEscherDataRecord.SplitRecords(var NextPos, RealSize: integer;
  var NextDwg: integer; const BreakList: TBreakList);
begin
  inherited;
  IncNextPos(NextPos, TotalDataSize, RealSize, BreakList);
end;

function TEscherDataRecord.TotalSizeNoSplit: int64;
begin
  Result:=inherited TotalSizeNoSplit + TotalDataSize;
end;

{ TEscherContainerRecord }

procedure TEscherContainerRecord.ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);
var
  i:integer;
begin
  inherited;
  for i:=0 to FContainedRecords.Count-1 do FContainedRecords[i].ArrangeInsertRowsAndCols(aRowPos, aRowCount, aColPos, aColCount, SheetInfo, Forced);
end;

procedure TEscherContainerRecord.AssignClientData(
  const aClientData: TBaseClientData);
begin
  LastRecord.AssignClientData(aClientData);
end;

procedure TEscherContainerRecord.ClearCopiedTo;
var
  i: integer;
begin
  inherited;
  for i:=0 to FContainedRecords.Count-1 do FContainedRecords[i].ClearCopiedTo;
end;

constructor TEscherContainerRecord.Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  inherited;
  FContainedRecords:= TEscherRecordList.Create;
end;

destructor TEscherContainerRecord.Destroy;
begin
  FreeAndNil(FContainedRecords);
  inherited;
end;

function TEscherContainerRecord.DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord;
begin
  Result:=inherited DoCopyTo(NewDwgCache, RowOfs, ColOfs);
  (Result as TEscherContainerRecord).FContainedRecords.CopyFrom(FContainedRecords, NewDwgCache, RowOfs, ColOfs);
end;

function TEscherContainerRecord.FindRec(const RecClass: ClassOfTEscherRecord): TEscherRecord;
var
  i: integer;
begin
  Result:=nil;
  for i:=0 to FContainedRecords.Count-1 do if FContainedRecords[i] is RecClass then
  begin
    Result:= FContainedRecords[i];
    exit;
  end;
end;

function TEscherContainerRecord.LastRecord: TEscherRecord;
begin
  if FContainedRecords.Count=0 then raise Exception.Create(ErrLoadingEscher);
  LastRecord:=FContainedRecords[FContainedRecords.Count-1];
end;

procedure TEscherContainerRecord.Load(var aRecord: TBaseRecord; var aPos: integer);
var
  RSize: integer;
  RecordHeader: TEscherRecordHeader;
begin
  RSize:= aRecord.TotalSizeNoHeaders;
  if aPos> RSize then raise Exception.Create(ErrExcelInvalid);
  while (not Loaded) and (aPos<RSize) do
  begin
    if (FContainedRecords.Count=0) or (LastRecord.Loaded) then
    begin
      ReadMem(aRecord, aPos, SizeOf(RecordHeader), @RecordHeader);
      if IsContainer(RecordHeader.Pre) then
        case RecordHeader.Id of
          MsofbtBstoreContainer:
               FContainedRecords.Add(TEscherBStoreRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtSpgrContainer:
               FContainedRecords.Add(TEscherSpgrContainerRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtSpContainer:
               FContainedRecords.Add(TEscherSpContainerRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtSolverContainer:
               FContainedRecords.Add(TEscherSolverContainerRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          else
               FContainedRecords.Add(TEscherContainerRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self))
        end // case
        else
        case RecordHeader.Id of
          MsofbtClientData:
               FContainedRecords.Add(TEscherClientDataRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtClientTextbox:
               FContainedRecords.Add(TEscherClientTextBoxRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtClientAnchor:
               FContainedRecords.Add(TEscherClientAnchorRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtBSE:
               FContainedRecords.Add(TEscherBSERecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtDg:
               FContainedRecords.Add(TEscherDgRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtDgg:
               FContainedRecords.Add(TEscherDggRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtSp:
               FContainedRecords.Add(TEscherSpRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtOPT:
               FContainedRecords.Add(TEscherOPTRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtSplitMenuColors:
               FContainedRecords.Add(TEscherSplitMenuRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));

          MsofbtConnectorRule:
               FContainedRecords.Add(TEscherConnectorRuleRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtAlignRule:
               FContainedRecords.Add(TEscherAlignRuleRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtArcRule:
               FContainedRecords.Add(TEscherArcRuleRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          MsofbtCallOutRule:
               FContainedRecords.Add(TEscherCallOutRuleRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
          else
               FContainedRecords.Add(TEscherDataRecord.Create(RecordHeader, DwgGroupCache, DwgCache, Self));
        end; //case
    end;
    LastRecord.Load(aRecord, aPos);
    if LastRecord.Loaded then
      begin
        inc(LoadedDataSize, LastRecord.TotalSizeNoSplit);
        LastRecord.AfterCreate;
      end;
  end;
end;

procedure TEscherContainerRecord.SaveToStream(const DataStream: TStream; const BreakList: TBreakList);
begin
  inherited;
  FContainedRecords.SaveToStream(DataStream, BreakList);
end;

procedure TEscherContainerRecord.SplitRecords(var NextPos, RealSize,
  NextDwg: integer; const BreakList: TBreakList);
var
  i: integer;
begin
  inherited;
  for i:=0 to FContainedRecords.Count-1 do FContainedRecords[i].SplitRecords(NextPos, RealSize, NextDwg, BreakList);
end;

function TEscherContainerRecord.TotalSizeNoSplit: int64;
begin
  Result:= inherited TotalSizeNoSplit+ FContainedRecords.TotalSizeNoSplit;
end;

function TEscherContainerRecord.WaitingClientData(var ClientType: ClassOfTBaseClientData): boolean;
begin
  if (FContainedRecords.Count=0) then Result:=false
  else Result:=LastRecord.WaitingClientData(ClientType);
end;

{ TEscherClientDataRecord }

procedure TEscherClientDataRecord.ArrangeCopyRowsAndCols(const RowOfs, ColOfs: integer);
begin
  if ClientData<>nil then ClientData.ArrangeCopyRowsAndCols(RowOfs, ColOfs);
end;

procedure TEscherClientDataRecord.ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);
begin
  inherited;
  if ClientData<>nil then ClientData.ArrangeInsertRowsAndCols(aRowPos, aRowCount, aColPos, aColCount, SheetInfo);
end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -