(*          GREATIS PRINT SUITE          *)
(*  Copyright (C) 2001 Greatis Software  *)
(*      web: http://www.greatis.com      *)
(*      e-mail: b-team@greatis.com       *)

unit PSDemoUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  PSJob, PSPreview, StdCtrls, Buttons, ExtCtrls, PSToolbar, PSLabel, PSCombo,
  PSStatusBar, PSWindow, TypInfo, ShellAPI, ComCtrls, Db, DBTables,
  PJGrid, PJTextGrid, PJDBGrid, PJSimpleGrid, PJSimpleTextGrid, Grids,
  PJStringGrid, PJListView, Printers, PJStrings, PJMulti, PJDraft,
  PJRichEdit, PJForm, PJControl, PJImage, PJBitmap, PJScreenshot;

type
  TfrmMain = class(TForm)
    psjAbout: TPrintJob;
    pswMain: TPreviewWindow;
    pnlPreview: TPanel;
    pstMain: TPreviewToolbar;
    Preview: TPreview;
    pssMain: TPreviewStatusBar;
    lblCategory: TLabel;
    lsbMain: TListBox;
    ntbMain: TNotebook;
    lblInfo: TLabel;
    lblWebTitle: TLabel;
    lblEMailTitle: TLabel;
    lblWeb: TLabel;
    lblEMail: TLabel;
    lblDocumentationTitle: TLabel;
    lblDocumentation: TLabel;
    pnlName: TPanel;
    imgIcon: TImage;
    pnlMargin: TPanel;
    psjAreas: TPrintJob;
    psjPublished: TPrintJob;
    lblAbout: TLabel;
    lblAreas: TLabel;
    lblPublished: TLabel;
    psjSimplest: TPrintJob;
    lblSimplest: TLabel;
    bvlMargin: TBevel;
    grbAreasOptions: TGroupBox;
    chbHeader: TCheckBox;
    chbFooter: TCheckBox;
    chbMargins: TCheckBox;
    grbHeader: TGroupBox;
    lblHeaderSize: TLabel;
    edtHeaderSize: TEdit;
    lblHeaderUnins: TLabel;
    cmbHeaderUnits: TComboBox;
    grbFooter: TGroupBox;
    lblFooterSize: TLabel;
    lblFooterUnits: TLabel;
    edtFooterSize: TEdit;
    cmbFooterUnits: TComboBox;
    grbMargins: TGroupBox;
    lblMarginsLeft: TLabel;
    lblMarginUnits: TLabel;
    edtMarginsLeft: TEdit;
    cmbMarginsUnits: TComboBox;
    edtMarginsRight: TEdit;
    lblMarginsRight: TLabel;
    lblMarginsTop: TLabel;
    edtMarginsTop: TEdit;
    edtMarginsBottom: TEdit;
    lblMarginsBottom: TLabel;
    lblAreaHint: TLabel;
    grbAreaLegend: TGroupBox;
    pnlHeader: TPanel;
    pnlPage: TPanel;
    pnlFooter: TPanel;
    lblPageCount: TLabel;
    edtPageCount: TEdit;
    udnPageCount: TUpDown;
    lblDBDetail: TLabel;
    tblDBDetail: TTable;
    psjDBDetail: TPrintJob;
    psjDBGrid: TDBGridPrintJob;
    tblDBGrid: TTable;
    tblDBGridFirst_Name: TStringField;
    tblDBGridLast_Name: TStringField;
    tblDBGridPhone: TStringField;
    tblDBGridFax: TStringField;
    dsrDBGrid: TDataSource;
    lblDBGrid: TLabel;
    psjSimpleGrid: TSimpleGridPrintJob;
    lblSimpleGrid: TLabel;
    psjSimpleTextGrid: TSimpleTextGridPrintJob;
    lblSimpleTextGrid: TLabel;
    lblStringGrid: TLabel;
    stgProducts: TStringGrid;
    pnlStringGridMargin: TPanel;
    btnStringGridUpdate: TButton;
    psjStringGrid: TStringGridPrintJob;
    lblStringGridColumns: TLabel;
    imlLarge: TImageList;
    imlSmall: TImageList;
    lblListView: TLabel;
    pnlListView: TPanel;
    lsvDemo: TListView;
    psjListView: TListViewPrintJob;
    lblListViewUpdate: TLabel;
    btnListViewUpdate: TButton;
    grbFooterBorders: TGroupBox;
    chbFLeft: TCheckBox;
    chbFRight: TCheckBox;
    chbFTop: TCheckBox;
    chbFBottom: TCheckBox;
    grbHeaderBorders: TGroupBox;
    chbHLeft: TCheckBox;
    chbHRight: TCheckBox;
    chbHTop: TCheckBox;
    chbHBottom: TCheckBox;
    grbPageBorders: TGroupBox;
    chbPLeft: TCheckBox;
    chbPRight: TCheckBox;
    chbPTop: TCheckBox;
    chbPBottom: TCheckBox;
    grbTableBorders: TGroupBox;
    chbTLeft: TCheckBox;
    chbTRight: TCheckBox;
    chbTTop: TCheckBox;
    chbTBottom: TCheckBox;
    lblHint: TLabel;
    lblDBHint: TLabel;
    lblRules: TLabel;
    psjRules: TPrintJob;
    psjStrings: TStringsPrintJob;
    lblStrings: TLabel;
    memStrings: TMemo;
    btnLoad: TButton;
    btnFont: TButton;
    opdStrings: TOpenDialog;
    fndStrings: TFontDialog;
    btnUpdate: TButton;
    lblStringsInstructions: TLabel;
    psjMulti: TMultiPrintJob;
    lblMulti: TLabel;
    btnEditPrintJobs: TButton;
    lblMultiInfo: TLabel;
    psjDraft: TDraftPrintJob;
    lblDraft: TLabel;
    cmbDraft: TComboBox;
    lblDraftPrintJob: TLabel;
    chbDraftSeparators: TCheckBox;
    lblDraftScale: TLabel;
    edtDraftScale: TEdit;
    udnDraftScale: TUpDown;
    chbWordWrap: TCheckBox;
    psjRichEdit: TRichEditPrintJob;
    opdRichEdit: TOpenDialog;
    lblRichEdit: TLabel;
    lblRichEditInstructions: TLabel;
    btnLoadRTF: TButton;
    btnRTFUpdate: TButton;
    redRichText: TRichEdit;
    psjPreviewProperties: TPrintJob;
    lblPreviewTitle: TLabel;
    grbPreviewMargins: TGroupBox;
    chbPreviewMarginsVisible: TCheckBox;
    lblPreviewMarginsFill: TLabel;
    lblPreviewMarginsBorder: TLabel;
    pnlPreviewMarginsFill: TPanel;
    btnPreviewMarginsFill: TButton;
    pnlPreviewMarginsBorder: TPanel;
    btnPreviewMarginsBorder: TButton;
    grbPreviewNonPrintable: TGroupBox;
    lblPreviewNonPrintableFill: TLabel;
    lblPreviewNonPrintableBorder: TLabel;
    chbPreviewNonPrintableVisible: TCheckBox;
    pnlPreviewNonPrintableFill: TPanel;
    btnPreviewNonPrintableFill: TButton;
    pnlPreviewNonPrintableBorder: TPanel;
    btnPreviewNonPrintableBorder: TButton;
    grbPreview: TGroupBox;
    lblPreviewColor: TLabel;
    lblPreviewShadowColor: TLabel;
    pnlPreviewColor: TPanel;
    btnPreviewColor: TButton;
    pnlPreviewShadowColor: TPanel;
    btnPreviewShadowColor: TButton;
    chbPreviewScrollTracking: TCheckBox;
    chbPreviewDragScroll: TCheckBox;
    chbPreviewUseMetafile: TCheckBox;
    cldPreview: TColorDialog;
    chbListViewSelectedOnly: TCheckBox;
    psjScreenshot: TScreenshotPrintJob;
    psjImage: TImagePrintJob;
    psjControl: TControlPrintJob;
    psjForm: TFormPrintJob;
    rgrBitmapPrintJob: TRadioGroup;
    btnBitmapUpdate: TButton;
    Label1: TLabel;
    Label2: TLabel;
    rgrHorAlign: TRadioGroup;
    rgrVerAlign: TRadioGroup;
    rgrBitmapStretchMode: TRadioGroup;
    pnlGreatisSoftware: TPanel;
    imgGreatisSoftware: TImage;
    procedure lblEMailClick(Sender: TObject);
    procedure lblLinkClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure lsbMainClick(Sender: TObject);
    procedure pstMainUserButtonClick(Sender: TObject);
    procedure psjInitDraw(Sender: TObject; TheCanvas: TCanvas;
      Target: TDrawTarget);
    procedure psjAboutDraw(Sender: TObject; TheCanvas: TCanvas;
      PageIndex: Integer; Rect: TRect; Area: TDrawArea;
      Target: TDrawTarget);
    procedure btnPreviewColorClick(Sender: TObject);
    procedure chbPreviewClick(Sender: TObject);
    procedure psjAreasDraw(Sender: TObject; TheCanvas: TCanvas;
      PageIndex: Integer; Rect: TRect; Area: TDrawArea;
      Target: TDrawTarget);
    procedure edtKeyPress(Sender: TObject; var Key: Char);
    procedure eveAreaChanged(Sender: TObject);
    procedure psjPublishedDraw(Sender: TObject; TheCanvas: TCanvas;
      PageIndex: Integer; Rect: TRect; Area: TDrawArea;
      Target: TDrawTarget);
    procedure psjSimplestDraw(Sender: TObject; TheCanvas: TCanvas;
      PageIndex: Integer; Rect: TRect; Area: TDrawArea;
      Target: TDrawTarget);
    procedure udnPageCountClick(Sender: TObject; Button: TUDBtnType);
    procedure psjRulesDraw(Sender: TObject; TheCanvas: TCanvas;
      PageIndex: Integer; Rect: TRect; Area: TDrawArea;
      Target: TDrawTarget);
    procedure psjDBDetailInitDraw(Sender: TObject; TheCanvas: TCanvas;
      Target: TDrawTarget);
    procedure psjDBDetailDraw(Sender: TObject; TheCanvas: TCanvas;
      PageIndex: Integer; Rect: TRect; Area: TDrawArea;
      Target: TDrawTarget);
    procedure psjSimpleTextGridColWidth(Sender: TObject;
      TheCanvas: TCanvas; ACol: Integer; var ColWidth: Integer);
    procedure psjSimpleTextGridCellText(Sender: TObject; APageIndex, ACol,
      ARow: Integer; var Text: String);
    procedure chbBorderClick(Sender: TObject);
    procedure psjSimpleGridColWidth(Sender: TObject;
      TheCanvas: TCanvas; ACol: Integer; var ColWidth: Integer);
    procedure psjSimpleGridInitDraw(Sender: TObject;
      TheCanvas: TCanvas; Target: TDrawTarget);
    procedure psjSimpleGridDrawCell(Sender: TObject;
      TheCanvas: TCanvas; Rect: TRect; PageIndex, ACol, ARow: Integer;
      Target: TDrawTarget);
    procedure btnStringGridUpdateClick(Sender: TObject);
    procedure lsvDemoEditing(Sender: TObject; Item: TListItem;
      var AllowEdit: Boolean);
    procedure btnListViewUpdateClick(Sender: TObject);
    procedure chbListViewSelectedOnlyClick(Sender: TObject);
    procedure btnLoadClick(Sender: TObject);
    procedure btnFontClick(Sender: TObject);
    procedure btnUpdateClick(Sender: TObject);
    procedure chbWordWrapClick(Sender: TObject);
    procedure btnLoadRTFClick(Sender: TObject);
    procedure btnRTFUpdateClick(Sender: TObject);
    procedure btnEditPrintJobsClick(Sender: TObject);
    procedure btnBitmapUpdateClick(Sender: TObject);
    procedure rgrBitmapPrintJobClick(Sender: TObject);
    procedure rgrHorAlignClick(Sender: TObject);
    procedure rgrVerAlignClick(Sender: TObject);
    procedure rgrBitmapStretchModeClick(Sender: TObject);
    procedure cmbDraftChange(Sender: TObject);
    procedure chbDraftSeparatorsClick(Sender: TObject);
    procedure udnDraftScaleClick(Sender: TObject; Button: TUDBtnType);
  private
    { Private declarations }
    procedure ApplicationHint(Sender: TObject);
    procedure SetPreviewProperties;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.DFM}

procedure TfrmMain.ApplicationHint(Sender: TObject);
begin
  pssMain.UserText:=GetShortHint(Application.Hint);
end;

procedure TfrmMain.lblEMailClick(Sender: TObject);
begin
  ShellExecute(
    Handle,
    'open',
    PChar('mailto:'+lblEMail.Caption+'?Subject=Print Suite'),
    nil,
    nil,
    SW_SHOWDEFAULT);
end;

procedure TfrmMain.lblLinkClick(Sender: TObject);
begin
  ShellExecute(
    Handle,
    'open',
    PChar((Sender as TLabel).Caption),
    nil,
    nil,
    SW_SHOWDEFAULT);
end;

procedure TfrmMain.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  Application.OnHint:=ApplicationHint;
  imgIcon.Picture.Icon.Assign(Application.Icon);
  if psjAbout.PrinterOK then Printer.Orientation:=poPortrait;
  lsbMain.ItemIndex:=0;
  lsbMain.OnClick(lsbMain);
  cmbHeaderUnits.ItemIndex:=2;
  cmbFooterUnits.ItemIndex:=2;
  cmbMarginsUnits.ItemIndex:=2;
  psjDBDetail.PageCount:=tblDBDetail.RecordCount;
  with stgProducts do
  begin
    Cols[0].Text:=
      'Product'#13#10+
      'Print Suite'#13#10+
      'TFormDesigner'#13#10+
      'WinDowse'#13#10+
      'TCoolorDialog';
    Cols[1].Text:=
      'Description'#13#10+
      'Components for print with preview'#13#10+
      'Run-time form designer'#13#10+
      'Advanced Windows analyser'#13#10+
      'Advanced color dialog component';
  end;
  with cmbDraft,Items,Self do
  begin
    for i:=0 to Pred(ComponentCount) do
      if (Components[i] is TCustomPrintJob) and
        not (Components[i] is TCustomMultiPrintJob) and
        (Components[i]<>psjMulti) and (Components[i]<>psjDraft) then
        cmbDraft.Items.AddObject(Components[i].Name+' - '+TCustomPrintJob(Components[i]).Title,Components[i]);
    if Count>0 then
    begin
      ItemIndex:=0;
      DropDownCount:=Count;
    end;
  end;
  redRichText.Lines.LoadFromFile(ExtractFilePath(Application.ExeName)+'PrintSuite.rtf');
  psjRichEdit.Update;
end;

procedure TfrmMain.lsbMainClick(Sender: TObject);
var
  OldOrientation: TPageOrientation;
begin
  with ntbMain do
    ActivePage:=Pages[lsbMain.ItemIndex];
  with Preview do
  begin
    OldOrientation:=PrintJob.Orientation;
    case lsbMain.ItemIndex of
      0: PrintJob:=psjAbout;
      1: PrintJob:=psjPreviewProperties;
      2: PrintJob:=psjAreas;
      3: PrintJob:=psjPublished;
      4: PrintJob:=psjSimplest;
      5: PrintJob:=psjRules;
      6: PrintJob:=psjDBDetail;
      7: PrintJob:=psjDBGrid;
      8: PrintJob:=psjSimpleTextGrid;
      9: PrintJob:=psjSimpleGrid;
      10: PrintJob:=psjStringGrid;
      11: PrintJob:=psjListView;
      12: PrintJob:=psjStrings;
      13: PrintJob:=psjRichEdit;
      14:
      begin
        rgrBitmapPrintJob.ItemIndex:=0;
        PrintJob:=psjScreenshot;
      end;
      15: PrintJob:=psjMulti;
      16: PrintJob:=psjDraft;
    end;
    if PrintJob.Orientation<>OldOrientation then Update;
    pstMain.UserButtonEnabled:=lsbMain.ItemIndex<>15;
    if not pstMain.UserButtonEnabled then pswMain.Close;
  end;
end;

procedure TfrmMain.pstMainUserButtonClick(Sender: TObject);
begin
  pswMain.Show;
end;

procedure TfrmMain.psjInitDraw(Sender: TObject; TheCanvas: TCanvas;
  Target: TDrawTarget);
begin
  TheCanvas.Font.Name:='Verdana';
end;

{ About Greatis Print Suite }

procedure TfrmMain.psjAboutDraw(Sender: TObject; TheCanvas: TCanvas;
  PageIndex: Integer; Rect: TRect; Area: TDrawArea;
  Target: TDrawTarget);
var
  Text: string;
begin
  with TheCanvas,Font,Rect do
    if Area=daPage then
    begin
      Rectangle(Left,Top,Right,Bottom);
      if PageIndex=1 then
      begin
        Size:=20;
        Style:=[fsBold];
        Text:='Greatis Print Suite';
        TextOut(
          Left+(Right-Left-TextWidth(Text)) div 2,
          Top+TextHeight(Text),
          Text);
        Size:=16;
        Style:=[];
        Text:='Meets all of your printing needs.';
        TextOut(
          Left+(Right-Left-TextWidth(Text)) div 2,
          Bottom-3*TextHeight(Text),
          Text);
        Text:='Print more, better, and easier!';
        TextOut(
          Left+(Right-Left-TextWidth(Text)) div 2,
          Bottom-2*TextHeight(Text),
          Text);
      end
      else
      begin
        Size:=16;
        Style:=[];
        Text:='http://www.greatis.com/printsuite.htm';
        TextOut(
          Left+(Right-Left-TextWidth(Text)) div 2,
          Top+TextHeight(Text),
          Text);
        Text:='Copyright © 2001 Greatis Software';
        TextOut(
          Left+(Right-Left-TextWidth(Text)) div 2,
          Bottom-2*TextHeight(Text),
          Text);
      end;
    end;
end;

{ Preview properties }

procedure TfrmMain.SetPreviewProperties;
begin
  with Preview do
  begin
    Color:=pnlPreviewColor.Color;
    ShadowColor:=pnlPreviewShadowColor.Color;
    ScrollTracking:=chbPreviewScrollTracking.Checked;
    DragScroll:=chbPreviewDragScroll.Checked;
    UseMetafile:=chbPreviewUseMetafile.Checked;
    NonPrintableVisible:=chbPreviewNonPrintableVisible.Checked;
    NonPrintableFill:=pnlPreviewNonPrintableFill.Color;
    NonPrintableBorder:=pnlPreviewNonPrintableBorder.Color;
    MarginsVisible:=chbPreviewMarginsVisible.Checked;
    MarginsFill:=pnlPreviewMarginsFill.Color;
    MarginsBorder:=pnlPreviewMarginsBorder.Color;
  end;
end;

procedure TfrmMain.btnPreviewColorClick(Sender: TObject);
var
  Panel: TPanel;
begin
  Panel:=FindComponent('pnl'+Copy((Sender as TButton).Name,4,255)) as TPanel;
  if Assigned(Panel) then
    with cldPreview do
    begin
      Color:=Panel.Color;
      if Execute then
      begin
        Panel.Color:=Color;
        SetPreviewProperties;
      end;
    end;
end;

procedure TfrmMain.chbPreviewClick(Sender: TObject);
begin
  SetPreviewProperties;
end;

{ Print job page areas }

procedure TfrmMain.psjAreasDraw(Sender: TObject; TheCanvas: TCanvas;
  PageIndex: Integer; Rect: TRect; Area: TDrawArea;
  Target: TDrawTarget);
begin
  with TheCanvas,Font,Rect do
  begin
    with Brush do
      case Area of
        daHeader: Color:=$CCFFCC;
        daPage: Color:=$CCCCFF;
        daFooter: Color:=$FFCCCC;
      end;
    FillRect(Rect);
  end;
end;

procedure TfrmMain.edtKeyPress(Sender: TObject; var Key: Char);
begin
  case Key of
    ',','.','0'..'9',Char(VK_BACK): ;
  else
  begin
    Key:=#0;
    MessageBeep(0);
  end;
  end;
end;

procedure TfrmMain.eveAreaChanged(Sender: TObject);
begin
  with psjAreas do
  begin
    LockUpdate;
    try
      Options:=[];
      if chbMargins.Checked then Options:=Options+[joMargins];
      if chbHeader.Checked then Options:=Options+[joHeader];
      if chbFooter.Checked then Options:=Options+[joFooter];
      MarginsUnits:=TUnits(cmbMarginsUnits.ItemIndex);
      with Margins do
      begin
        try
          Left:=StrToFloat(edtMarginsLeft.Text);
        except
        end;
        try
          Right:=StrToFloat(edtMarginsRight.Text);
        except
        end;
        try
          Top:=StrToFloat(edtMarginsTop.Text);
        except
        end;
        try
          Bottom:=StrToFloat(edtMarginsBottom.Text);
        except
        end;
      end;
      HeaderUnits:=TUnits(cmbHeaderUnits.ItemIndex);
      try
        Header:=StrToFloat(edtHeaderSize.Text);
      except
      end;
      FooterUnits:=TUnits(cmbFooterUnits.ItemIndex);
      try
        Footer:=StrToFloat(edtFooterSize.Text);
      except
      end;
    finally
      UnlockUpdate;
      Update;
    end;
  end;
end;

{ Published interface of Print Suite components }

procedure TfrmMain.psjPublishedDraw(Sender: TObject; TheCanvas: TCanvas;
  PageIndex: Integer; Rect: TRect; Area: TDrawArea;
  Target: TDrawTarget);

  procedure DrawPublished(AClass: TPersistentClass);
  var
    i: Integer;
    Info: PTypeInfo;
    Data: PTypeData;
    PropList: PPropList;
  begin
    Info:=AClass.ClassInfo;
    Data:=GetTypeData(Info);
    GetMem(PropList,Data^.PropCount*SizeOf(PPropInfo));
    with Rect,TheCanvas,Font do
      try
        case Area of
          daHeader:
          begin
            Size:=20;
            Style:=[fsBold];
            TextOut(
              Left+(Right-Left-TextWidth(AClass.ClassName)) div 2,
              Top+(Bottom-Top-TextHeight(AClass.ClassName)) div 2,
              AClass.ClassName);
          end;
          daPage:
          begin
            Size:=10;
            // draw properties list
            Style:=[fsBold];
            TextOut(Left,Top,'Properties');
            Style:=[];
            for i:=0 to Pred(GetPropList(Info,tkProperties,PropList)) do
              with PropList[i]^ do
                TextOut(Left,Top+(i+2)*3*Abs(Height) div 2,Name);
            // draw events list
            Style:=[fsBold];
            TextOut(Left+(Right-Left) div 2,Top,'Events');
            Style:=[];
            for i:=0 to Pred(GetPropList(Info,tkMethods,PropList)) do
              with PropList[i]^ do
                TextOut(Left+(Right-Left) div 2,Top+(i+2)*3*Abs(Height) div 2,Name);
          end;
        end;
      finally
        FreeMem(PropList,Data^.PropCount*SizeOf(PPropInfo));
      end;
  end;

begin
  with TheCanvas,Font,Rect do
    case PageIndex of
      1: DrawPublished(TPrintJob);
      2: DrawPublished(TPreview);
      3: DrawPublished(TPreviewWindow);
      4: DrawPublished(TPreviewToolbar);
      5: DrawPublished(TPreviewStatusBar);
      6: DrawPublished(TPreviewComboBox);
      7: DrawPublished(TPreviewLabel);
      8: DrawPublished(TSimpleGridPrintJob);
      9: DrawPublished(TSimpleTextGridPrintJob);
      10: DrawPublished(TStringGridPrintJob);
      11: DrawPublished(TDBGridPrintJob);
      12: DrawPublished(TListViewPrintJob);
      13: DrawPublished(TStringsPrintJob);
      14: DrawPublished(TRichEditPrintJob);
      15: DrawPublished(TScreenshotPrintJob);
      16: DrawPublished(TImagePrintJob);
      17: DrawPublished(TControlPrintJob);
      18: DrawPublished(TFormPrintJob);
      19: DrawPublished(TMultiPrintJob);
      20: DrawPublished(TDraftPrintJob);
    end;
end;

{ Simplest realization of print job }

procedure TfrmMain.psjSimplestDraw(Sender: TObject; TheCanvas: TCanvas;
  PageIndex: Integer; Rect: TRect; Area: TDrawArea; Target: TDrawTarget);
var
  S: string;
begin
  if Area=daPage then
    with Rect,TheCanvas,Font do
    begin
      // drawing page rectangle
      Rectangle(Left,Top,Right,Bottom);
      // setting font properties
      Name:='Arial';
      Size:=200;
      Style:=[fsBold];
      // drawing text
      S:=IntToStr(PageIndex);
      TextOut(
        (Left+Right-TextWidth(S)) div 2,
        (Top+Bottom-TextHeight(S)) div 2,
        S);
    end;
end;

procedure TfrmMain.udnPageCountClick(Sender: TObject; Button: TUDBtnType);
begin
  psjSimplest.PageCount:=udnPageCount.Position;
end;

{ Exact size graphic printing }

procedure TfrmMain.psjRulesDraw(Sender: TObject; TheCanvas: TCanvas;
  PageIndex: Integer; Rect: TRect; Area: TDrawArea; Target: TDrawTarget);
var
  i,RW,X,L,LB,LM,LS: Integer;
  TR: TRect;
begin
  with Sender as TPrintJob,TheCanvas,Rect do
  begin
    // set font parameters
    with Font do
    begin
      Name:='Verdana';
      Height:=-Round(InchToPix(0.1,dirVertical));
    end;
    // calculate lines length
    LB:=Round(InchToPix(0.3,dirVertical));
    LM:=Round(0.75*InchToPix(0.3,dirVertical));
    LS:=Round(0.5*InchToPix(0.3,dirVertical));
    // draw center line
    MoveTo(Left,(Bottom+Top) div 2);
    LineTo(Right,(Bottom+Top) div 2);
    // rule mm width calculate
    RW:=Trunc(PixToMm(Right-Left-Round(InchToPix(0.2,dirHorizontal)),dirHorizontal));
    // draw mm rule
    for i:=0 to RW do
    begin
      X:=Left+Round(InchToPix(0.1,dirHorizontal)+MmToPix(i,dirHorizontal));
      MoveTo(X,(Bottom+Top) div 2);
      case i mod 10 of
        0:
        begin
          L:=LB; // big lines
          // create null-size rect
          TR:=Classes.Rect(X,(Bottom+Top) div 2-L,X,(Bottom+Top) div 2-L);
          // draw with NOCLIP options
          DrawText(Handle,PChar(IntToStr(i)),-1,TR,
            DT_SINGLELINE or DT_CENTER or DT_NOCLIP or DT_BOTTOM);
        end;
        5: L:=LM; // medium lines
      else L:=LS; // small lines
      end;
      LineTo(X,(Bottom+Top) div 2-L);
    end;
    // draw mm label
    TR:=Classes.Rect(
      Left,(Bottom+Top) div 2-2*LB,Left,(Bottom+Top) div 2-2*LB);
    DrawText(Handle,'millimeters',-1,TR,
      DT_SINGLELINE or DT_LEFT or DT_NOCLIP or DT_BOTTOM);
    // rule inches width calculate
    RW:=Trunc(10*PixToInch(Right-Left-Round(InchToPix(0.2,dirHorizontal)),dirHorizontal));
    // draw inches rule
    for i:=0 to RW do
    begin
      X:=Left+Round(InchToPix(0.1,dirHorizontal)+InchToPix(i,dirHorizontal)/10);
      MoveTo(X,(Bottom+Top) div 2);
      case i mod 10 of
        0:
        begin
          L:=LB; // big lines
          // create null-size rect
          TR:=Classes.Rect(X,(Bottom+Top) div 2+L,X,(Bottom+Top) div 2+L);
          // draw with NOCLIP options
          DrawText(Handle,PChar(IntToStr(i div 10)),-1,TR,
            DT_SINGLELINE or DT_CENTER or DT_NOCLIP or DT_TOP);
        end;
        5: L:=LM; // medium lines
      else L:=LS; // small lines
      end;
      LineTo(X,(Bottom+Top) div 2+L);
    end;
    // draw inches label
    TR:=Classes.Rect(
      Left,(Bottom+Top) div 2+2*LB,Left,(Bottom+Top) div 2+2*LB);
    DrawText(Handle,'inches',-1,TR,
      DT_SINGLELINE or DT_LEFT or DT_NOCLIP or DT_TOP);
  end;
end;

{ Database detail printing - one record in one page }

procedure TfrmMain.psjDBDetailInitDraw(Sender: TObject;
  TheCanvas: TCanvas; Target: TDrawTarget);
begin
  TheCanvas.Font.Name:='Arial';
end;

procedure TfrmMain.psjDBDetailDraw(Sender: TObject; TheCanvas: TCanvas;
  PageIndex: Integer; Rect: TRect; Area: TDrawArea; Target: TDrawTarget);

var
  R: TRect;
  Text: string;
  Y: Integer;
  Bitmap: TBitmap;

  procedure DrawFieldText(var Y: Integer; FieldName,FieldValue: string);
  begin
    with TheCanvas,Rect do
    begin
      TextOut(Left,Y,FieldName);
      Inc(Y,TextHeight(FieldName));
      TextOut(Left,Y,FieldValue);
      Inc(Y,2*Abs(Font.Height));
    end;
  end;

begin
  with Sender as TPrintJob,tblDBDetail,TheCanvas,Font,Rect do
  begin
    RecNo:=PageIndex;
    case Area of
      daHeader:
      begin
        Size:=28;
        Style:=[fsBold];
        TextOut(Left,Top,Fields[2].AsString);
        MoveTo(Left,Bottom);
        LineTo(Right,Bottom);
      end;
      daPage:
      begin
        Y:=Top+Round(InchToPix(1,dirVertical));
        Bitmap:=TBitmap.Create;
        try
          with Bitmap do
          begin
            Bitmap.Assign(Fields[7]);
            R:=
              Classes.Rect(
                (Left+Right) div 2,
                Y,
                Right,
                Y+Height*(Right-Left) div 2 div Width);
          end;
          DrawBitmap(TheCanvas,R,Bitmap,Target);
        finally
          Bitmap.Free;
        end;
        Size:=13;
        Style:=[fsBold];
        DrawFieldText(Y,'Category',Fields[1].AsString);
        DrawFieldText(Y,'Species name',Fields[3].AsString);
        DrawFieldText(Y,'Length',Format('%0.0f cm / %0.1f inches',[Fields[4].AsFloat,Fields[5].AsFloat]));
        Text:=Fields[6].AsString;
        Inc(Y,Round(InchToPix(1,dirVertical)));
        Style:=[];
        R:=Classes.Rect(Left,Y,Right,Bottom);
        DrawText(TheCanvas.Handle,PChar(Text),Length(Text),R,DT_WORDBREAK);
      end;
      daFooter:
      begin
        Size:=10;
        Style:=[];
        Text:='Greatis Print Suite Demo. Copyright © 2001 Greatis Software';
        TextOut(Left,Bottom-TextHeight(Text),Text);
        Text:=Format('Page %d from %d',[PageIndex,PageCount]);
        TextOut(Right-TextWidth(Text),Bottom-TextHeight(Text),Text);
        MoveTo(Left,Top);
        LineTo(Right,Top);
      end;
    end;
  end;
end;

{ Database printing in grid mode - NO MANUAL CODE ! }

{ Simplest text grid printing }

procedure TfrmMain.psjSimpleTextGridColWidth(Sender: TObject;
  TheCanvas: TCanvas; ACol: Integer; var ColWidth: Integer);
begin
  with Sender as TSimpleTextGridPrintJob,GetPageRect do
    ColWidth:=(Right-Left) div ColCount;
end;

procedure TfrmMain.psjSimpleTextGridCellText(Sender: TObject; APageIndex,
  ACol, ARow: Integer; var Text: String);
begin
  case ARow of
    rowHeader: Text:=Format('H.%d',[ACol]);
    rowFooter: Text:=Format('F.%d',[ACol]);
  else Text:=Format('%d.%d',[ACol,ARow]);
  end;
end;

procedure TfrmMain.chbBorderClick(Sender: TObject);
begin
  with psjSimpleTextGrid do
  try
    LockUpdate;
    HeaderCellBorders:=[];
    if chbHLeft.Checked then HeaderCellBorders:=HeaderCellBorders+[cbLeft];
    if chbHRight.Checked then HeaderCellBorders:=HeaderCellBorders+[cbRight];
    if chbHTop.Checked then HeaderCellBorders:=HeaderCellBorders+[cbTop];
    if chbHBottom.Checked then HeaderCellBorders:=HeaderCellBorders+[cbBottom];
    FooterCellBorders:=[];
    if chbFLeft.Checked then FooterCellBorders:=FooterCellBorders+[cbLeft];
    if chbFRight.Checked then FooterCellBorders:=FooterCellBorders+[cbRight];
    if chbFTop.Checked then FooterCellBorders:=FooterCellBorders+[cbTop];
    if chbFBottom.Checked then FooterCellBorders:=FooterCellBorders+[cbBottom];
    PageCellBorders:=[];
    if chbPLeft.Checked then PageCellBorders:=PageCellBorders+[cbLeft];
    if chbPRight.Checked then PageCellBorders:=PageCellBorders+[cbRight];
    if chbPTop.Checked then PageCellBorders:=PageCellBorders+[cbTop];
    if chbPBottom.Checked then PageCellBorders:=PageCellBorders+[cbBottom];
    TableBorders:=[];
    if chbTLeft.Checked then TableBorders:=TableBorders+[cbLeft];
    if chbTRight.Checked then TableBorders:=TableBorders+[cbRight];
    if chbTTop.Checked then TableBorders:=TableBorders+[cbTop];
    if chbTBottom.Checked then TableBorders:=TableBorders+[cbBottom];
  finally
    UnlockUpdate;
    Update;
  end;
end;

{ Simplest graphic grid printing }

type
  TColorData = record
    C: TColor;
    N: string;
  end;

const
  Colors: array[0..15] of TColorData = (
    (C: clBlack; N: 'Black'),
    (C: clMaroon; N: 'Maroon'),
    (C: clGreen; N: 'Green'),
    (C: clOlive; N: 'Olive'),
    (C: clNavy; N: 'Navy'),
    (C: clPurple; N: 'Purple'),
    (C: clTeal; N: 'Teal'),
    (C: clGray; N: 'Gray'),
    (C: clSilver; N: 'Silver'),
    (C: clRed; N: 'Red'),
    (C: clLime; N: 'Lime'),
    (C: clYellow; N: 'Yellow'),
    (C: clBlue; N: 'Blue'),
    (C: clFuchsia; N: 'Fuchsia'),
    (C: clAqua; N: 'Aqua'),
    (C: clWhite; N: 'White'));


procedure TfrmMain.psjSimpleGridColWidth(Sender: TObject;
  TheCanvas: TCanvas; ACol: Integer; var ColWidth: Integer);
var
  PW: Integer;
begin
  with (Sender as TCustomPrintJob).GetPageRect do PW:=Right-Left;
  case ACol of
    colIndex,0: ColWidth:=PW div 10
  else ColWidth:=8*PW div 30;
  end;
end;

procedure TfrmMain.psjSimpleGridInitDraw(Sender: TObject;
  TheCanvas: TCanvas; Target: TDrawTarget);
begin
  with TheCanvas.Font do
  begin
    Name:='Arial';
    Size:=12;
  end;
end;

procedure TfrmMain.psjSimpleGridDrawCell(Sender: TObject;
  TheCanvas: TCanvas; Rect: TRect; PageIndex, ACol, ARow: Integer;
  Target: TDrawTarget);
var
  Text: string;
  RGB: Integer;
begin
  with Sender as TSimpleGridPrintJob,TheCanvas,Rect do
  begin
    case ARow of
      rowHeader:
      begin
        case ACol of
          colIndex: Text:='#';
          0: Text:='C';
          1: Text:='Name';
          2: Text:='RGB Hex';
          3: Text:='RGB Decimal';
        end;
        Font.Style:=[fsBold];
      end;
      rowFooter: ;
    else
    begin
      case ACol of
        colIndex: Text:=IntToStr(ARow+IndexStart);
        0:
        begin
          Brush.Color:=Colors[ARow].C;
          InflateRect(Rect,-(Right-Left) div 5,-(Bottom-Top) div 5);
          Rectangle(Left,Top,Right,Bottom);
          Exit;
        end;
        1: Text:=Colors[ARow].N;
        2,3:
        begin
          RGB:=ColorToRGB(Colors[ARow].C);
          if ACol=2 then Text:=Format('%2.2x%2.2x%2.2x',[GetRValue(RGB),GetGValue(RGB),GetBValue(RGB)])
          else Text:=Format('%d,%d,%d',[GetRValue(RGB),GetGValue(RGB),GetBValue(RGB)]);
        end;
      end;
      Font.Style:=[];
    end;
    end;
    Brush.Color:=clWhite;
    TextOut(
      (Left+Right-TextWidth(Text)) div 2,
      (Top+Bottom-TextHeight(Text)) div 2,
      Text);
  end;
end;

{ TStringGrid contents printing }

procedure TfrmMain.btnStringGridUpdateClick(Sender: TObject);
begin
  psjStringGrid.Update;
end;

{ TListView contents printing }

procedure TfrmMain.lsvDemoEditing(Sender: TObject; Item: TListItem;
  var AllowEdit: Boolean);
begin
  AllowEdit:=False;
end;

procedure TfrmMain.btnListViewUpdateClick(Sender: TObject);
begin
  psjListView.Update;
end;

procedure TfrmMain.chbListViewSelectedOnlyClick(Sender: TObject);
begin
  psjListView.SelectedOnly:=chbListViewSelectedOnly.Checked;
end;

{ TStrings printing }

procedure TfrmMain.btnLoadClick(Sender: TObject);
begin
  with opdStrings do
    if Execute then
    begin
      memStrings.Lines.LoadFromFile(FileName);
      psjStrings.Strings.LoadFromFile(FileName);
      psjStrings.Update;
    end;
end;

procedure TfrmMain.btnFontClick(Sender: TObject);
begin
  with fndStrings do
  begin
    Font:=memStrings.Font;
    if Execute then
    begin
      memStrings.Font:=Font;
      psjStrings.Font:=memStrings.Font;
    end;
  end;
end;

procedure TfrmMain.chbWordWrapClick(Sender: TObject);
begin
  psjStrings.WordWrap:=chbWordWrap.Checked;
end;

procedure TfrmMain.btnUpdateClick(Sender: TObject);
begin
  psjStrings.Strings:=memStrings.Lines;
end;

{ TRichEdit printing }

procedure TfrmMain.btnLoadRTFClick(Sender: TObject);
begin
  with opdRichEdit do
    if Execute then
    begin
      redRichText.Lines.LoadFromFile(FileName);
      psjRichEdit.Update;
    end;
end;

procedure TfrmMain.btnRTFUpdateClick(Sender: TObject);
begin
  psjRichEdit.Update;
end;

{ Bitmap print jobs }

procedure TfrmMain.btnBitmapUpdateClick(Sender: TObject);
begin
  if Preview.PrintJob is TCustomBitmapPrintJob then
    TCustomBitmapPrintJob(Preview.PrintJob).UpdateBitmap;
end;

procedure TfrmMain.rgrBitmapPrintJobClick(Sender: TObject);
begin
  case rgrBitmapPrintJob.ItemIndex of
    0: Preview.PrintJob:=psjScreenshot;
    1: Preview.PrintJob:=psjImage;
    2: Preview.PrintJob:=psjControl;
  else Preview.PrintJob:=psjForm;
  end;
  with TCustomBitmapPrintJob(Preview.PrintJob) do
  begin
    rgrHorAlign.ItemIndex:=Ord(AlignHorizontal);
    rgrVerAlign.ItemIndex:=Ord(AlignVertical);
    rgrBitmapStretchMode.ItemIndex:=Ord(StretchMode);
    UpdateBitmap;
  end;
end;

procedure TfrmMain.rgrHorAlignClick(Sender: TObject);
begin
  if Preview.PrintJob is TCustomBitmapPrintJob then
    TCustomBitmapPrintJob(Preview.PrintJob).AlignHorizontal:=TAlignHorizontal(rgrHorAlign.ItemIndex);
end;

procedure TfrmMain.rgrVerAlignClick(Sender: TObject);
begin
  if Preview.PrintJob is TCustomBitmapPrintJob then
    TCustomBitmapPrintJob(Preview.PrintJob).AlignVertical:=TAlignVertical(rgrVerAlign.ItemIndex);
end;

procedure TfrmMain.rgrBitmapStretchModeClick(Sender: TObject);
begin
  if Preview.PrintJob is TCustomBitmapPrintJob then
    TCustomBitmapPrintJob(Preview.PrintJob).StretchMode:=TStretchMode(rgrBitmapStretchMode.ItemIndex);
end;

{ Multi-job printing }

procedure TfrmMain.btnEditPrintJobsClick(Sender: TObject);
begin
  psjMulti.EditPrintJobs;
end;

{ Draft printing }

procedure TfrmMain.cmbDraftChange(Sender: TObject);
begin
  with cmbDraft,Items do
    psjDraft.PrintJob:=TCustomPrintJob(Objects[ItemIndex]);
end;

procedure TfrmMain.chbDraftSeparatorsClick(Sender: TObject);
begin
  psjDraft.Separators:=chbDraftSeparators.Checked;
end;

procedure TfrmMain.udnDraftScaleClick(Sender: TObject; Button: TUDBtnType);
begin
  psjDraft.Scale:=udnDraftScale.Position;
end;

end.
