📄 tmsuescherrecords.pas
字号:
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 (aRecord.Continue = nil) and (aPos = aRecord.DataSize) then exit; //There is nothing more to read, we need to load the next record from disk. This can happen when reading nested MsObjs.
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: TOle2File; 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(out ClientType: ClassOfTBaseClientData): boolean;
begin
if (FContainedRecords.Count=0) then begin; Result:=false; ClientType:=nil; end
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; const dSheet: TObject);
begin
inherited;
if ClientData<>nil then ClientData.ArrangeInsertRowsAndCols(aRowPos, aRowCount, aColPos, aColCount, SheetInfo);
end;
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; const dSheet: TObject): TEscherRecord;
begin
Result:=inherited DoCopyTo(NewDwgCache, RowOfs, ColOfs, dSheet);
(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: TOle2File; 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(out ClientType: ClassOfTBaseClientData): boolean;
begin
Result:= inherited Loaded and (ClientData=nil);
ClientType:=TMsObj;
end;
//------------------------------------Other Records--------------------------//
{ 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; const sSheet: TObject);
begin
Create(aEscherHeader, aDwgGroupCache, aDwgCache, aParent);
move(aAnchor, Anchor^, Sizeof(TClientAnchor));
LoadedDataSize:=TotalDataSize;
SaveObjectCoords(sSheet);
end;
procedure TEscherClientAnchorRecord.ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount: integer; const SheetInfo: TSheetInfo; const Forced: boolean; const dSheet: TObject);
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;
1, 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;
RestoreObjectCoords(dSheet);
end;
3: //dont move
begin
RestoreObjectCoords(dSheet);
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; const dSheet: TObject): TEscherRecord;
begin
Result:=inherited DoCopyTo(NewDwgCache, RowOfs, ColOfs, dSheet);
(Result.FParent as TEscherSPContainerRecord).ClientAnchor:=Result as TEscherClientAnchorRecord;
(Result as TEscherClientAnchorRecord).SaveRect := SaveRect;
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);
RestoreObjectCoords(dSheet);
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; const sSheet: TObject);
begin
move(aAnchor, Anchor^, Sizeof(TClientAnchor));
SaveObjectCoords(sSheet);
end;
procedure CalcAbsCol(const Workbook: TWorkSheet; const Col, Deltax: integer; out x: integer);
var
c: integer;
begin
x :=0;
for c:=0 to Col - 1 do
inc(x, Workbook.GetColWidth(c, true));
inc(x, Round(Workbook.GetColWidth(Col, true)*Deltax/1024.0));
end;
procedure CalcAbsRow(const Workbook: TWorkSheet; const Row, Deltay: integer; out y: integer);
var
r: integer;
begin
y :=0;
for r:=0 to Row - 1 do
inc(y, Workbook.GetRowHeight(r, true));
inc(y, Round(Workbook.GetRowHeight(Row, true)*Deltay/255.0));
end;
procedure CalcColAndDx(const Workbook: TWorkSheet; const RectX: integer; out Column, Deltax: integer);
var
Col, x, Lastx: integer;
fw: double;
begin
Col:=0;
x:=0;
Lastx :=0;
while (Col<=Max_Columns) and (x<= RectX) do
begin
Lastx := x;
inc (x, Workbook.GetColWidth(Col, true));
inc(Col);
end;
Column := Col-1;
if (Column<0) then
begin
Column:=0;
Deltax:=0;
end
else
begin
fw := Workbook.GetColWidth(Column, true);
if (Workbook.GetColWidth(Column, true)>0) then
Deltax := Round((RectX-Lastx) / fw * 1024.0)
else Deltax:=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -