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

📄 uescherrecords.pas

📁 TMS component pack v4.2 for delphi
💻 PAS
📖 第 1 页 / 共 4 页
字号:

procedure TEscherClientDataRecord.AssignClientData(const aClientData: TBaseClientData);
begin
  ClientData:= aClientData;
  if (ClientData<>nil) then
  begin
    if (ClientData.Id> DwgCache.MaxObjId) then DwgCache.MaxObjId:=ClientData.Id;
  end;
end;

constructor TEscherClientDataRecord.Create( const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  inherited;
  if DwgCache.Obj<>nil then DwgCache.Obj.Add(Self);
end;

constructor TEscherClientDataRecord.CreateFromData(
  const aDwgGroupCache: PEscherDwgGroupCache;
  const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
var
  aEscherHeader: TEscherRecordHeader;
begin
  aEscherHeader.Pre:=0;
  aEscherHeader.Id:=MsofbtClientData;
  aEscherHeader.Size:=0;
  Create( aEscherHeader, aDwgGroupCache, aDwgCache, aParent);
  LoadedDataSize:=0;
end;

destructor TEscherClientDataRecord.Destroy;
begin
  if (DwgCache.Obj<>nil) and not DwgCache.Destroying then DwgCache.Obj.Remove(Self);
  FreeAndNil(ClientData);
  //MADE: remover los otros que referencian a estos objs.
  inherited;
end;

function TEscherClientDataRecord.DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord;
begin
  Result:=inherited DoCopyTo(NewDwgCache, RowOfs, ColOfs);
  (Result as TEscherClientDataRecord).AssignClientData(ClientData.CopyTo);

  if NewDwgCache=DwgCache then (Result as TEscherClientDataRecord).ClientData.ArrangeId(DwgCache.MaxObjId);
  (Result as TEscherClientDataRecord).ArrangeCopyRowsAndCols(RowOfs, ColOfs);
end;

function TEscherClientDataRecord.Loaded: boolean;
begin
  Result:= inherited Loaded;
end;

function TEscherClientDataRecord.ObjId: word;
begin
  if ClientData<>nil then Result:=ClientData.Id else Result:=0;
end;

procedure TEscherClientDataRecord.SaveToStream(const DataStream: TStream; const BreakList: TBreakList);
var
  StreamPos: integer;
begin
  inherited;
  StreamPos:= DataStream.Position;
  if ClientData<>nil then ClientData.SaveToStream(DataStream);
  BreakList.AddToZeroPos(DataStream.Position-StreamPos);

end;

procedure TEscherClientDataRecord.SplitRecords(var NextPos,
  RealSize: integer; var NextDwg: integer; const BreakList: TBreakList);
begin
  inherited;
  if ClientData<>nil then inc(RealSize, ClientData.TotalSize);
  NextDwg:=xlr_MSODRAWING;
end;

function TEscherClientDataRecord.TotalSizeNoSplit: int64;
begin
  TotalSizeNoSplit:=inherited TotalSizeNoSplit;
end;

function TEscherClientDataRecord.WaitingClientData(var ClientType: ClassOfTBaseClientData): boolean;
begin
  Result:= inherited Loaded and (ClientData=nil);
  ClientType:=TMsObj;
end;

//////////////////////////////////////Other Records ///////////////////////////7

{ TEscherClientAnchorRecord }

constructor TEscherClientAnchorRecord.Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  inherited;
  Anchor:=PClientAnchor(Data);
  if DwgCache.Anchor<>nil then DwgCache.Anchor.Add(Self);
  if FParent <> nil then (FParent as TEscherSPContainerRecord).ClientAnchor:=Self;
end;

constructor TEscherClientAnchorRecord.CreateFromData(const aAnchor: TClientAnchor;const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  Create(aEscherHeader, aDwgGroupCache, aDwgCache, aParent);
  move(aAnchor, Anchor^, Sizeof(TClientAnchor));
  LoadedDataSize:=TotalDataSize;
end;

procedure TEscherClientAnchorRecord.ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean);
var
  dr, dc: integer;
  Af: word;
begin
  if SheetInfo.FormulaSheet<> SheetInfo.InsSheet then exit;
  if Forced then Af:=2 else Af:=Anchor.Flag;
  case Af and 3 of
    0: //move and resize
    begin
      //Rows
      if Anchor.Row1>=aRowPos then
      begin
        dr:= Anchor.Row1+aRowCount;
        IncMaxMin(Anchor.Row1, aRowCount, Max_Rows, aRowPos);
        if dr< aRowPos then Anchor.Dy1:=0;
      end;
      if Anchor.Row2>=aRowPos then
      begin
        dr:= Anchor.Row2+aRowCount;
        IncMaxMin(Anchor.Row2, aRowCount, Max_Rows, aRowPos);
        if dr< aRowPos then Anchor.Dy2:=0;
      end;

      //Columns
      if Anchor.Col1>=aColPos then
      begin
        dc:= Anchor.Col1+aColCount;
        IncMaxMin(Anchor.Col1, aColCount, Max_Columns, aColPos);
        if dc< aColPos then Anchor.Dx1:=0;
      end;
      if Anchor.Col2>=aColPos then
      begin
        dc:= Anchor.Col2+aColCount;
        IncMaxMin(Anchor.Col2, aColCount, Max_Columns, aColPos);
        if dc< aColPos then Anchor.Dx2:=0;
      end;
    end;
    2: //move
    begin
      if Anchor.Row1>=aRowPos then
      begin
        dr:= Anchor.Row1;
        IncMaxMin(Anchor.Row1, aRowCount, Max_Rows, aRowPos);
        IncMaxMin(Anchor.Row2, Anchor.Row1-dr, Max_Rows, Anchor.Row1);
      end;
      if Anchor.Col1>=aColPos then
      begin
        dc:= Anchor.Col1;
        IncMaxMin(Anchor.Col1, aColCount, Max_Columns, aColPos);
        IncMaxMin(Anchor.Col2, Anchor.Col1-dc, Max_Columns, Anchor.Col1);
      end;
    end;
    3: //dont move
    begin
    end;
  end; //case
end;


destructor TEscherClientAnchorRecord.Destroy;
begin
  if (DwgCache.Anchor<> nil) and not DwgCache.Destroying then DwgCache.Anchor.Remove(Self);
  if FParent <> nil then (FParent as TEscherSpContainerRecord).ClientAnchor:=nil;
  inherited;
end;

function TEscherClientAnchorRecord.AllowCopy(const FirstRow, LastRow, FirstCol, LastCol: integer): boolean;
begin
  AllowCopy:= ((Anchor.Flag and 3) in [0,2])
              and (Anchor.Row1>=FirstRow) and (Anchor.Row2<=LastRow)
              and (Anchor.Col1>=FirstCol) and (Anchor.Col2<=LastCol);
end;

function TEscherClientAnchorRecord.AllowDelete(const FirstRow, LastRow, FirstCol, LastCol: integer): boolean;
begin
  AllowDelete:= ((Anchor.Flag and 3) in [0])
                 and (Anchor.Row1>=FirstRow) and (Anchor.Row2<=LastRow)
                 and (Anchor.Col1>=FirstCol) and (Anchor.Col2<=LastCol);
end;

function TEscherClientAnchorRecord.DoCopyTo(const NewDwgCache: PEscherDwgCache; const RowOfs, ColOfs: integer): TEscherRecord;
begin
  Result:=inherited DoCopyTo(NewDwgCache, RowOfs, ColOfs);
  (Result.FParent as TEscherSPContainerRecord).ClientAnchor:=Result as TEscherClientAnchorRecord;
  inc((Result as TEscherClientAnchorRecord).Anchor.Row1, RowOfs);
  inc((Result as TEscherClientAnchorRecord).Anchor.Row2, RowOfs);
  inc((Result as TEscherClientAnchorRecord).Anchor.Col1, ColOfs);
  inc((Result as TEscherClientAnchorRecord).Anchor.Col2, ColOfs);
end;

function TEscherClientAnchorRecord.Col: integer;
begin
  Result:= Anchor.Col1;
end;

function TEscherClientAnchorRecord.Row: integer;
begin
  Result:= Anchor.Row1;
end;

function TEscherClientAnchorRecord.GetAnchor: TClientAnchor;
begin
  Result:= Anchor^;
end;


procedure TEscherClientAnchorRecord.SetAnchor(
  const aAnchor: TClientAnchor);
begin
  move(aAnchor, Anchor^, Sizeof(TClientAnchor));
end;

{ TEscherBSERecord }

procedure TEscherBSERecord.AddRef;
begin
  IncLongWord(Data,24,1);
end;

function TEscherBSERecord.CompareRec( const aRecord: TEscherRecord): integer;
type
  TUid=array[0..15] of byte;
  PUid=^TUid;
var
  Uid1, Uid2: PUid;
  i:integer;
begin
  //We can't just compare the data of the 2 records, because cRef can be different
  //no inherited

  if TotalDataSize< aRecord.TotalDataSize then Result:=-1 else if TotalDataSize> aRecord.TotalDataSize then Result:=1 else
  begin
    Uid1:= PUid(PChar(Data)+2);
    Uid2:= PUid(PChar((aRecord as TEscherBSERecord).Data)+2);
    for i:=0 to SizeOf(TUid)-1 do
      if Uid1[i]<Uid2[i] then
      begin
        Result:=-1;
        exit;
      end else
      if Uid1[i]>Uid2[i] then
      begin
        Result:=1;
        exit;
      end;

    Result:= 0;
  end;
end;

procedure TEscherBSERecord.CopyFromData(
  const BSEHeader: Pointer; const BlipHeader: TEscherRecordHeader; const BlipData: TStream);
var
  blp: PArrayOfByte;
begin
  if 36+BlipData.Size+SizeOf(BlipHeader)<> TotalDataSize then raise exception.Create(ErrInternal);
  System.Move(BSEHeader^, Data^, 36);
  System.Move(BlipHeader, (PChar(Data)+36)^, SizeOf(BlipHeader));
  blp:=PArrayOfByte(pchar(Data)+36+SizeOf(BlipHeader));
  BlipData.Read(blp^, BlipData.Size);
  LoadedDataSize:=TotalDataSize;
end;

function TEscherBSERecord.References: LongWord;
begin
  References:= GetLongWord(Data, 24);
end;

procedure TEscherBSERecord.Release;
begin
  if self=nil then exit;
  IncLongWord(Data,24,-1);
  if (References=0)and (DwgGroupCache.BStore<>nil) then
    DwgGroupCache.BStore.ContainedRecords.Remove(Self); //When refs=0 , delete from bstore
end;

//This is the header to write a bitmap to disk
type
  tagBITMAPFILEHEADER = packed record
    bfType: Word;
    bfSize: LongWord;
    bfReserved1: Word;
    bfReserved2: Word;
    bfOffBits: LongWord;
  end;

procedure TEscherBSERecord.SaveGraphicToStream(const aData: TStream; var aDataType: TXlsImgTypes);
var
  HeadOfs: integer;
  BmpHead: tagBITMAPFILEHEADER;
begin
  case Data[0] of
    msoblipEMF  : aDataType:=xli_Emf;
    msoblipWMF  : aDataType:=xli_Wmf;
    msoblipJPEG : aDataType:=xli_Jpeg;
    msoblipPNG  : aDataType:=xli_Png;
    msoblipDIB  : aDataType:=xli_Bmp;
    else aDataType:=xli_Unknown;
  end; //case
  if aDataType in [xli_JPEG, xli_PNG, xli_BMP] then HeadOfs:=17 else HeadOfs:=16;

  if aDataType = xli_Bmp then
  begin
    FillChar(BmpHead, SizeOf(BmpHead), 0);
    BmpHead.BfType:=$4D42;
    aData.WriteBuffer(BmpHead, SizeOf(BmpHead));
  end;

  aData.WriteBuffer((PChar(Data)+36+SizeOf(TEscherRecordHeader)+HeadOfs)^ , TotalDataSize-36-SizeOf(TEscherRecordHeader)-HeadOfs);
end;

{ TEscherBStoreRecord }

procedure TEscherBStoreRecord.AddRef(const BlipPos: integer);
begin
  if (BlipPos<1)or(BlipPos> FContainedRecords.Count) then raise Exception.Create(ErrExcelInvalid);
  (FContainedRecords[BlipPos-1] as TEscherBSERecord).AddRef;
end;

constructor TEscherBStoreRecord.Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  inherited;
  if (DwgGroupCache.BStore=nil) then DwgGroupCache.BStore:=Self else raise Exception.Create(ErrBStroreDuplicated);
end;

destructor TEscherBStoreRecord.Destroy;
begin
  DwgGroupCache.BStore:=nil;
  inherited;
end;

procedure TEscherBStoreRecord.Release(const BlipPos: integer);
begin
  if (BlipPos<1)or(BlipPos> FContainedRecords.Count) then raise Exception.Create(ErrExcelInvalid);
  (FContainedRecords[BlipPos-1] as TEscherBSERecord).Release;
end;

procedure TEscherBStoreRecord.SaveToStream(const DataStream: TStream;
  const BreakList: TBreakList);
var
  i: integer;
begin
  //Fix bse positions
  for i:=0 to FContainedRecords.Count-1 do (FContainedRecords[i] as TEscherBSERecord).BStorePos:=i+1;
  inherited;
end;

{ TEscherDgRecord }

constructor TEscherDgRecord.Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  inherited;
  Dg:= Pdg(Data);
  if (DwgCache.Dg=nil) then DwgCache.Dg:=Self else raise Exception.Create(ErrDgDuplicated);
end;

constructor TEscherDgRecord.CreateFromData(const csp, cspidCur: LongWord;
  const aDwgGroupCache: PEscherDwgGroupCache;
  const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
var
  EscherHeader: TEscherRecordHeader;
begin
  EscherHeader.Pre:=$10;
  EscherHeader.Id:=MsofbtDg;
  EscherHeader.Size:=2*SizeOf(LongWord);
  Create(EscherHeader, aDwgGroupCache, aDwgCache, aParent);
  SetLongWord(Data, 0, csp);
  SetLongWord(Data, 4, cspidCur);
  LoadedDataSize:=TotalDataSize;
end;

procedure TEscherDgRecord.DecShapeCount;
begin
  dec(Dg.ShapeCount);
end;

destructor TEscherDgRecord.Destroy;
begin
  DwgCache.Dg:=nil;
  inherited;
end;

function TEscherDgRecord.IncMaxShapeId: LongWord;
begin
  inc(Dg^.MaxSpId);
  Result:= Dg^.MaxSpId;
  inc(Dg^.ShapeCount);
  //PENDING: cuando llega a 1024, new dgg group
end;

{ TEscherSPRecord }

constructor TEscherSPRecord.Create(const aEscherHeader: TEscherRecordHeader; const aDwgGroupCache: PEscherDwgGroupCache; const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
begin
  inherited;
  ShapeId:=PLongWord(Data);
  if DwgCache.Shape<>nil then DwgCache.Shape.Add(Self);
  if FParent <> nil then (FParent as TEscherSpContainerRecord).SP:=self;
end;

constructor TEscherSPRecord.CreateFromData(const Pre, aShapeId, Flags: LongWord;
  const aDwgGroupCache: PEscherDwgGroupCache;
  const aDwgCache: PEscherDwgCache; const aParent: TEscherContainerRecord);
var
  RecordHeader: TEscherRecordHeader;
begin
  RecordHeader.Id:=MsofbtSp;
  RecordHeader.Pre:=Pre;
  RecordHeader.Size:=8;

  Create(RecordHeader, aDwgGroupCache, aDwgCache, aParent);
  ShapeId^:=aShapeId;
  SetLongWord(Data, 4, Flags);
  LoadedDataSize:=RecordHeader.Size;

end;

destructor TEscherSPRecord.Destroy;
var
  Index: integer;
begin
  if not DwgCache.Destroying then
  begin
    if DwgCache.Dg<>nil then  DwgCache.Dg.DecShapeCount;

⌨️ 快捷键说明

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