unit AlPrev;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, AlRep;

type
  TAlPreview = class(TScrollBox)     // tScrollingWinControl ???
  private
    { Private-Deklarationen }
    fPage   : integer;
    fZoom   : integer;
    pbxPage : tPaintbox;
    FTitle  : string;
    fBusy   : boolean;
    {m}FPages: TPages;
       FOwnPages: TPages;
    {/m}
    procedure SetPageNumber(value:integer);
    function  GetPageCount:integer;
    procedure SetZoom (value:integer);
    procedure UpdatePage(Sender:tObject);
    procedure pbxMouseDown(Sender:tObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  protected
    { Protected-Deklarationen }
    {m}procedure SetPages(APages: TPages);{/m}
  public
    {m}{/m FPages  : TPages;}
    { Public-Deklarationen }
    constructor Create (aOwner:tComponent); override;
    destructor Destroy; override;
    procedure  FirstPage;
    procedure  LastPage;
    procedure  NextPage;
    procedure  PrevPage;
    procedure  Print (pfrom,pto:integer);
    property PageNumber:integer read fPage write SetPageNumber;
    property Zoom:integer read fZoom write SetZoom default 100;
    property PageCount:integer read GetPageCount;
    property Busy:boolean read FBusy;
    {m}property Pages: TPages read FPages write SetPages;{/m}
  published
    { Published-Deklarationen }
    property Title: string read FTitle write FTitle;
  end;

procedure Register;

implementation
uses
  Printers;

{$R alprev.res} // eventuell gehts so
const
  crMyCursor = 5;

constructor TAlPreview.Create(aOwner:tComponent);
begin
  inherited Create (aOwner);

  fPage  := 1;
  fZoom := 100;
  fBusy := false;

  pbxPage := TPaintBox.Create(Self);
  pbxPage.Parent := Self;

  pbxPage.Left        := 15;
  pbxPage.Top         := 15;
  pbxPage.Width       := 823;   // Din A4 screen width
  pbxPage.Height      := 1164; // Din A4 screen height
  pbxPage.ParentColor := false;
  pbxPage.Color       := clWhite;

  pbxPage.OnMouseDown := pbxMouseDown;
  pbxPage.Cursor      := crMyCursor;
  // pbxPage.Cursor := crNo;  // klappt

  if NOT (csDesigning in ComponentState) then begin
    FPages := tPages.Create;
    {m}FOwnPages := FPages;{/m}
  end;
  pbxPage.OnPaint := UpdatePage;
end;

{m}
procedure TAlPreview.SetPages(APages: TPages);
begin
  if APages <> nil then begin
    FPages := APages;
  end else begin
    FPages := FOwnPages;
  end;
end;
{/m}

destructor TAlPreview.Destroy;
begin
  if not (csDesigning in ComponentState) then
   begin
     FOwnPages.Clear;
     FOwnPages.Free;
   end;
  pbxPage.Free;
  inherited destroy;
end;

procedure TAlPreview.UpdatePage(Sender:tObject);
begin
  if NOT (csDesigning in ComponentState) then
   begin
     pbxPage.Width := Round(AlPrinter.PageWidth*fZoom/100.0);
     pbxPage.Height := Round(AlPrinter.PageHeight*fZoom/100.0);
   end;
  VertScrollBar.Range := pbxPage.Height+30;
  HorzScrollBar.Range := pbxPage.Width+30;
  pbxPage.Canvas.Brush.Color := clWhite;
  pbxPage.Canvas.FillRect (pbxPage.ClientRect);
  if NOT (csDesigning in ComponentState) then
     if (fPage>0) and (fPage<=PageCount) then
        pbxPage.Canvas.StretchDraw(pbxPage.ClientRect,FPages[fPage-1]);
end;

procedure TAlPreview.SetPageNumber(value:integer);
begin
  if (value>0) and (value<=AlPrinter.PageCount) then
   begin
     fPage := value;
     UpdatePage (Self);
   end;
end;

function TAlPreview.GetPageCount:integer;
begin
  result := FPages.Count;
end;

procedure TAlPreview.SetZoom(value:integer);
begin
  if value<>fZoom then
   if (value>=25) and (value<=200) then
    begin
      fZoom := value;
      UpdatePage (Self);
    end;
end;

procedure TAlPreview.FirstPage;
begin
  SetPageNumber (1);
end;

procedure TAlPreview.LastPage;
begin
  if PageCount>0 then
     SetPageNumber (PageCount);
end;

procedure TAlPreview.NextPage;
begin
  if fPage<PageCount then
   begin
     inc (fPage);
     UpdatePage (Self);
   end;
end;

procedure TAlPreview.PrevPage;
begin
  if fPage>1 then
   begin
     dec(fPage);
     UpdatePage (Self);
   end;
end;

procedure TAlPreview.Print (pFrom,pTo:integer);
var
   i : Integer;
{   s : String;}
begin
  FBusy := true;
  if PageCount > 0 then
   begin
     Printer.Orientation := AlPrinter.Orientation;
     Printer.Title := Title;
     if not Printer.Printing then
        Printer.BeginDoc;
     i := pFrom;
     try
       Printer.Canvas.StretchDraw( Rect(0,0,Printer.PageWidth,
                                            Printer.PageHeight),
                                   FPages[i-1]);
       for i := pFrom+1 to pTo do
        begin
          Printer.NewPage;
          Printer.Canvas.StretchDraw( Rect(0,0,Printer.PageWidth,
                                               Printer.PageHeight),
                                      FPages[i-1]);
        end;
     finally
        Printer.EndDoc;
     end; // try ... finally
   end; // if PageCount>0
  FBusy := false;
end; // procedure TAlPreview.Print

procedure TAlPreview.pbxMouseDown (Sender:tObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button=mbLeft then // Zoom in
     case fZoom of
        50 : Zoom :=  75;
        75 : Zoom := 100;
       100 : Zoom := 150;
       150 : Zoom := 200;
     end
  else if Button=mbRight then // Zoom out
     case fZoom of
       200 : Zoom := 150;
       150 : Zoom := 100;
       100 : Zoom :=  75;
        75 : Zoom :=  50;
     end;
  if Assigned(OnMouseDown) then
     OnMouseDown(Sender,Button,Shift,X,Y);
end;

procedure Register;
begin
  RegisterComponents('AlRep', [TAlPreview]);
end;

initialization
  Screen.Cursors[crMyCursor] := LoadCursor (hInstance,'LUPE');

finalization

end.
