📄 frxpreviewpages.pas
字号:
l := p.AllObjects;
for i := 0 to l.Count - 1 do
begin
c := l[i];
c.FBaseName := xs.WriteComponentStr(c);
end;
end;
{ fill FDictionary.Objects }
procedure FillDictionary;
var
i: Integer;
Name, PageName, ObjName: String;
PageN: Integer;
begin
xi := FXMLDoc.Root.FindItem('dictionary');
FDictionary.Clear;
for i := 0 to xi.Count - 1 do
begin
Name := Copy(xi[i].Text, 7, Length(xi[i].Text) - 7);
PageName := Copy(Name, 1, Pos('.', Name) - 1);
ObjName := Copy(Name, Pos('.', Name) + 1, 255);
PageN := StrToInt(Copy(PageName, 5, 255));
FDictionary.Add(xi[i].Name, Name,
TfrxReportPage(FSourcePages[PageN]).FindObject(ObjName));
end;
end;
begin
FPagesItem := FXMLDoc.Root.FindItem('previewpages');
xs := TfrxXMLSerializer.Create(nil);
{ load the report settings }
xi := FXMLDoc.Root.FindItem('report');
if xi.Count > 0 then
xs.ReadRootComponent(Report, xi[0]);
{ build sourcepages }
try
xi := FXMLDoc.Root.FindItem('sourcepages');
ClearSourcePages;
for i := 0 to xi.Count - 1 do
begin
if CompareText(xi[i].Name, 'TfrxDMPPage') = 0 then
p := TfrxDMPPage.Create(nil) else
p := TfrxReportPage.Create(nil);
xs.ReadRootComponent(p, xi[i]);
DoProps(p);
FSourcePages.Add(p);
end;
xi.Clear;
finally
xs.Free;
end;
{ build the dictionary }
FillDictionary;
end;
procedure TfrxPreviewPages.BeforeSave;
var
i: Integer;
xs: TfrxXMLSerializer;
xi: TfrxXMLItem;
begin
FPagesItem := FXMLDoc.Root.FindItem('previewpages');
xs := TfrxXMLSerializer.Create(nil);
{ upload the report settings }
xi := FXMLDoc.Root.FindItem('report');
xi.Clear;
xi := xi.Add;
xi.Name := Report.ClassName;
xi.Text := 'DotMatrixReport="' + frxValueToXML(Report.DotMatrixReport) +
'" PreviewOptions.OutlineVisible="' + frxValueToXML(Report.PreviewOptions.OutlineVisible) +
'" PreviewOptions.OutlineWidth="' + frxValueToXML(Report.PreviewOptions.OutlineWidth) + '"';
{ upload the sourcepages }
try
xi := FXMLDoc.Root.FindItem('sourcepages');
xi.Clear;
for i := 0 to FSourcePages.Count - 1 do
xs.WriteRootComponent(FSourcePages[i], True, xi.Add);
finally
xs.Free;
end;
{ upload the dictionary }
xi := FXMLDoc.Root.FindItem('dictionary');
xi.Clear;
for i := 0 to FDictionary.Names.Count - 1 do
with xi.Add do
begin
Name := FDictionary.Names[i];
Text := 'name="' + FDictionary.GetSourceName(Name) + '"';
end;
end;
function TfrxPreviewPages.GetObject(const Name: String): TfrxComponent;
begin
Result := TfrxComponent(FDictionary.GetObject(Name));
end;
function TfrxPreviewPages.GetPage(Index: Integer): TfrxReportPage;
var
xi: TfrxXMLItem;
xs: TfrxXMLSerializer;
i: Integer;
Source: TfrxReportPage;
procedure DoObjects(Item: TfrxXMLItem; Owner: TfrxComponent);
var
i: Integer;
c, c0: TfrxComponent;
begin
for i := 0 to Item.Count - 1 do
begin
c0 := GetObject(Item[i].Name);
{ object not found in the dictionary }
if c0 = nil then
c := xs.ReadComponentStr(Owner, Item[i].Name + ' ' + Item[i].Text)
else
begin
c := xs.ReadComponentStr(Owner, THackComponent(c0).FBaseName + ' ' + Item[i].Text);
c.Name := c0.Name;
end;
c.Parent := Owner;
DoObjects(Item[i], c);
end;
end;
begin
Result := nil;
if Count = 0 then Exit;
{ check pagecache first }
if not Engine.Running then
begin
i := FPageCache.IndexOf(IntToStr(Index));
if i <> -1 then
begin
Result := TfrxReportPage(FPageCache.Objects[i]);
FPageCache.Exchange(i, 0);
Exit;
end;
end;
xs := TfrxXMLSerializer.Create(nil);
try
{ load the page item }
xi := FPagesItem[Index];
FXMLDoc.LoadItem(xi);
if CompareText(xi.Name, 'TfrxReportPage') = 0 then
begin
{ page item do not refer to the originalpages }
Result := TfrxReportPage.Create(nil);
xs.ReadRootComponent(Result, xi);
end
else if CompareText(xi.Name, 'TfrxDMPPage') = 0 then
begin
{ page item do not refer to the originalpages }
Result := TfrxDMPPage.Create(nil);
xs.ReadRootComponent(Result, xi);
end
else
begin
Source := FSourcePages[StrToInt(Copy(xi.Name, 5, 5))];
{ create reportpage and assign properties from original page }
if Source is TfrxDMPPage then
Result := TfrxDMPPage.Create(nil) else
Result := TfrxReportPage.Create(nil);
Result.Assign(Source);
{ create objects }
DoObjects(xi, Result);
end;
finally
xs.Free;
end;
{ update aligned objects }
Result.AlignChildren;
{ add this page to the pagecache }
FPageCache.InsertObject(0, IntToStr(Index), Result);
i := FPageCache.Count;
{ remove the least used item from the pagecache }
if i > 50 then
begin
xi := FPagesItem[StrToInt(FPageCache[i - 1])];
if Report.EngineOptions.UseFileCache and xi.Unloadable then
begin
FXMLDoc.UnloadItem(xi);
xi.Clear;
end;
TfrxReportPage(FPageCache.Objects[i - 1]).Free;
FPageCache.Delete(i - 1);
end;
end;
function TfrxPreviewPages.GetPageSize(Index: Integer): TPoint;
var
xi: TfrxXMLItem;
p: TfrxReportPage;
begin
if (Count = 0) or (Index < 0) or (Index >= Count) then
begin
Result := Point(0, 0);
Exit;
end;
xi := FPagesItem[Index];
if (CompareText(xi.Name, 'TfrxReportPage') = 0) or
(CompareText(xi.Name, 'TfrxDMPPage') = 0) then
p := GetPage(Index) else
p := FSourcePages[StrToInt(Copy(xi.Name, 5, 256))];
Result.X := Round(p.Width);
Result.Y := Round(p.Height);
end;
procedure TfrxPreviewPages.AddEmptyPage(Index: Integer);
var
xi: TfrxXMLItem;
begin
if Count = 0 then Exit;
xi := TfrxXMLItem.Create;
xi.Name := FPagesItem[Index].Name;
FPagesItem.InsertItem(Index, xi);
ClearPageCache;
end;
procedure TfrxPreviewPages.DeletePage(Index: Integer);
begin
if Count < 2 then Exit;
FPagesItem[Index].Free;
ClearPageCache;
end;
procedure TfrxPreviewPages.ModifyPage(Index: Integer; Page: TfrxReportPage);
var
xs: TfrxXMLSerializer;
begin
xs := TfrxXMLSerializer.Create(nil);
try
FPagesItem[Index].Clear;
xs.WriteRootComponent(Page, True, FPagesItem[Index]);
FPagesItem[Index].Unloadable := False;
ClearPageCache;
finally
xs.Free;
end;
end;
procedure TfrxPreviewPages.AddFrom(Report: TfrxReport);
var
i: Integer;
Page: TfrxReportPage;
xi: TfrxXMLItem;
xs: TfrxXMLSerializer;
begin
xs := TfrxXMLSerializer.Create(nil);
for i := 0 to Report.PreviewPages.Count - 1 do
begin
Page := Report.PreviewPages.Page[i];
xi := TfrxXMLItem.Create;
xi.Name := FPagesItem[Count - 1].Name;
xs.WriteRootComponent(Page, True, xi);
xi.Unloadable := False;
FPagesItem.AddItem(xi);
end;
xs.Free;
ClearPageCache;
end;
procedure TfrxPreviewPages.DrawPage(Index: Integer; Canvas: TCanvas;
ScaleX, ScaleY, OffsetX, OffsetY: Extended);
var
i: Integer;
Page: TfrxReportPage;
l: TList;
c: TfrxComponent;
IsPrinting: Boolean;
SaveLeftMargin, SaveRightMargin: Extended;
rgn: HRGN;
function ViewVisible(c: TfrxComponent): Boolean;
var
r: TRect;
begin
with c do
r := Rect(Round(AbsLeft * ScaleX) - 20, Round(AbsTop * ScaleY) - 20,
Round((AbsLeft + Width) * ScaleX + 20),
Round((AbsTop + Height) * ScaleY + 20));
OffsetRect(r, Round(OffsetX), Round(OffsetY));
Result := RectVisible(Canvas.Handle, r) or (Canvas is TMetafileCanvas);
end;
begin
Page := GetPage(Index);
if Page = nil then Exit;
SaveLeftMargin := Page.LeftMargin;
SaveRightMargin := Page.RightMargin;
if Page.MirrorMargins and (Index mod 2 = 1) then
begin
Page.LeftMargin := SaveRightMargin;
Page.RightMargin := SaveLeftMargin;
end;
IsPrinting := Canvas is TfrxPrinterCanvas;
rgn := 0;
if not IsPrinting then
begin
rgn := CreateRectRgn(0, 0, 10000, 10000);
GetClipRgn(Canvas.Handle, rgn);
IntersectClipRect(Canvas.Handle,
Round(OffsetX),
Round(OffsetY),
Round(OffsetX + Page.PaperWidth * fr01cm * ScaleX) - 1,
Round(OffsetY + Page.PaperHeight * fr01cm * ScaleY) - 1);
end;
Page.Draw(Canvas, ScaleX, ScaleY, OffsetX, OffsetY);
OffsetX := OffsetX + Page.LeftMargin * fr01cm * ScaleX;
OffsetY := OffsetY + Page.TopMargin * fr01cm * ScaleY;
l := Page.AllObjects;
for i := 0 to l.Count - 1 do
begin
c := l[i];
if (c is TfrxView) and ViewVisible(c) then
if not IsPrinting or TfrxView(c).Printable then
begin
c.IsPrinting := IsPrinting;
{ needed for TOTALPAGES macro }
if c is TfrxCustomMemoView then
THackMemoView(c).FTotalPages := Count;
{ draw the object }
TfrxView(c).Draw(Canvas, ScaleX, ScaleY, OffsetX, OffsetY);
c.IsPrinting := False;
end;
end;
Page.LeftMargin := SaveLeftMargin;
Page.RightMargin := SaveRightMargin;
if not IsPrinting then
begin
SelectClipRgn(Canvas.Handle, rgn);
DeleteObject(rgn);
end;
end;
function TfrxPreviewPages.Print: Boolean;
var
Copies, PagesPrinted, ACopyNo: Integer;
Collate: Boolean;
PageNumbers: String;
PrintPages: TfrxPrintPages;
Reverse: Boolean;
pgList: TStringList;
LastDuplexMode: TfrxDuplexMode;
LastPaperSize, LastPaperWidth, LastPaperHeight, LastBin: Integer;
LastOrientation: TPrinterOrientation;
procedure DoPrint;
var
i: Integer;
Printer: TfrxCustomPrinter;
PagePrinted: Boolean;
Page: TfrxReportPage;
function PrintPage(Index: Integer): Boolean;
var
Bin, ACopies, cp: Integer;
begin
Result := True;
if Index >= Count then Exit;
if (pgList.Count <> 0) and (pgList.IndexOf(IntToStr(Index + 1)) = -1) then Exit;
if ((PrintPages = ppOdd) and ((Index + 1) mod 2 = 0)) or
((PrintPages = ppEven) and ((Index + 1) mod 2 = 1)) then Exit;
if Report.Terminated then
begin
Printer.Abort;
Result := False;
Exit;
end;
Page := GetPage(Index);
if Collate then
begin
ACopies := 1;
cp := ACopyNo;
end
else
begin
ACopies := Copies;
cp := 1;
end;
if Assigned(Report.OnPrintPage) then
Report.OnPrintPage(Page, cp);
if Index = 0 then
Bin := Page.Bin else
Bin := Page.BinOtherPages;
if (not PagePrinted) or
((LastPaperSize <> Page.PaperSize) or
(LastPaperWidth <> Round(Page.PaperWidth)) or
(LastPaperHeight <> Round(Page.PaperHeight)) or
(LastBin <> Bin) or
(LastOrientation <> Page.Orientation) or
(LastDuplexMode <> Page.Duplex)) then
Printer.SetPrintParams(Page.PaperSize, Page.PaperWidth, Page.PaperHeight,
Page.Orientation, Bin, Integer(Page.Duplex) + 1, ACopies);
if not PagePrinted then
Printer.BeginDoc;
Printer.BeginPage;
DrawPage(Index, Printer.Canvas, Printer.DPI.X / 96, Printer.DPI.Y / 96,
-Printer.LeftMargin * Printer.DPI.X / 25.4,
-Printer.TopMargin * Printer.DPI.Y / 25.4);
Report.InternalOnProgress(ptPrinting, Index + 1);
{$IFDEF TRIAL}
with Printer.Canvas do
begin
Font.Size := 12;
Font.Color := clBlack;
TextOut(0, 0, frxReverseString(FR_UNREG));
end;
{$ENDIF}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -