unit MFSRVPrint;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  SRVPrint, ExtCtrls, RVScroll, CRVPP, SRVPreview, SclRView, StdCtrls, Printers,
  RVStyle, jpeg;

type
  TFSRVPrint = class(TForm)
    srve: TSRichViewEdit;
    srvprvw: TSRVPreview;
    Splitter1: TSplitter;
    SRVPrint1: TSRVPrint;
    Panel1: TPanel;
    cmbDocPageFormat: TComboBox;
    cmbPrinterPageFormat: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    cmbPrinter: TComboBox;
    btnPreview: TButton;
    cbAutoUpdate: TCheckBox;
    imgTop: TImage;
    imgBottom2: TImage;
    imgBottom: TImage;
    imgLeft: TImage;
    imgRight: TImage;
    Label4: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure cmbDocPageFormatChange(Sender: TObject);
    procedure cmbPrinterChange(Sender: TObject);
    procedure btnPreviewClick(Sender: TObject);
    procedure cbAutoUpdateClick(Sender: TObject);
    procedure cmbPrinterPageFormatChange(Sender: TObject);
    procedure srvprvwBeforePaint(Sender: TObject; ACanvas: TCanvas; ARect: TRect);
    procedure FormResize(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure InfoOfPrinter;
  end;

var
  FSRVPrint: TFSRVPrint;

implementation

{$R *.DFM}

procedure TFSRVPrint.InfoOfPrinter;
var
     index, indexFormat : Integer;
begin
  cmbPrinterPageFormat.Clear;
  with SRVPrint1.SRVPrtInfo do begin
    UpdateCurPrinterData;
    indexFormat := -1;
    for index := 0 to (PaperFormatsList.Count-1) do
      begin
        if (PaperFormatsList.Items[index].PaperSizeCode = PaperSizeCode) then
          indexFormat := index;
        if (Trim(SRVPrint1.SRVPrtInfo.PaperFormatsList.Items[index].Name) <> '') then
          cmbPrinterPageFormat.Items.Append(SRVPrint1.SRVPrtInfo.PaperFormatsList.Items[index].Name);
      end;
  end;
  cmbPrinterPageFormat.ItemIndex := indexFormat;
end;

procedure TFSRVPrint.FormCreate(Sender: TObject);
var
     index : Integer;
begin
  // Printers
  if (Printer.Printers.Count > 0) then
    for index := 0 to (Printer.Printers.Count-1) do
      cmbPrinter.Items.Append(Printer.Printers.Strings[index]);
  cmbPrinter.ItemIndex := Printer.PrinterIndex;

  // Paper
  InfoOfPrinter;

  // Page
  // In this demo, we limit list of doc format with page sizes available for
  // the printer. In general, it is not necessary
  cmbDocPageFormat.Items.Assign(cmbPrinterPageFormat.Items);
  cmbDocPageFormat.ItemIndex := cmbPrinterPageFormat.ItemIndex;
  Printer.Orientation := poLandscape;
  srve.LoadRVF('poster.rvf');
  cmbDocPageFormatChange(nil);
  SRVPrint1.Update;

  cbAutoUpdateClick(nil);
end;

procedure TFSRVPrint.cmbPrinterChange(Sender: TObject);
begin
  if (Printer.Printers.Count > 0) then
    begin
      Printer.PrinterIndex := cmbPrinter.ItemIndex;
      InfoOfPrinter;
      cmbPrinterPageFormatChange(nil);
    end;
end;

procedure TFSRVPrint.cmbDocPageFormatChange(Sender: TObject);
var
     PageFormat : TSRVPageFormat;
     index, w, h : Integer;
begin
  index := cmbDocPageFormat.ItemIndex;
  if (index = -1) then
    Exit;

  with SRVPrint1.SRVPrtInfo do begin
    // PaperSize is measured in tenths of a millimeter
    PageFormat := srve.PageProperty.ConvertPageSizeToPageFormat(rvuMillimeters,
                    Round(PaperFormatsList.Items[index].PaperSize.x / 10),
                    Round(PaperFormatsList.Items[index].PaperSize.y / 10));
    srve.PageProperty.PageFormat := PageFormat;
    if (PageFormat = srvfmCustom) then begin
        w := Round(
          PaperFormatsList.Items[index].PaperSize.x *
          srve.UnitsPerInchH(srve.UnitsProgram)/
          srve.UnitsPerInchH(rvuMillimeters)/10);
        h := Round(
          PaperFormatsList.Items[index].PaperSize.y *
          srve.UnitsPerInchV(srve.UnitsProgram)/
          srve.UnitsPerInchV(rvuMillimeters)/10);
        if srve.PageProperty.Orientation = poPortrait then begin
          srve.PageProperty.PageWidth := w;
          srve.PageProperty.PageHeight := h;
          end
        else begin
          srve.PageProperty.PageWidth := h;
          srve.PageProperty.PageHeight := w;
        end;
    end
  end;
  cmbPrinterPageFormatChange(nil);
end;

procedure TFSRVPrint.cmbPrinterPageFormatChange(Sender: TObject);
var
     index : Integer;
     Device : array[0..255] of char;
     Driver : array[0..255] of char;
     Port   : array[0..255] of char;
     hDMode : THandle;
     PDMode : PDEVMODE;
begin
  index := cmbPrinterPageFormat.ItemIndex;
  if (index = -1) then
    Exit;

  Printer.PrinterIndex := Printer.PrinterIndex;
  Printer.GetPrinter(Device, Driver, Port, hDMode);
  if hDMode <> 0 then begin
    pDMode := GlobalLock(hDMode);
    if pDMode <> nil then begin
     {Set to custom size}
      pDMode^.dmFields := pDMode^.dmFields or
                          DM_PAPERSIZE;
      pDMode^.dmPaperSize :=
        SRVPrint1.SRVPrtInfo.PaperFormatsList.Items[index].PaperSizeCode;

     {Set the bin to use}
      pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
      pDMode^.dmDefaultSource := DMBIN_MANUAL;

      GlobalUnlock(hDMode);
    end;
  end;
  Printer.SetPrinter(Device, Driver, Port, hDMode);

  SRVPrint1.Update;
  srvprvw.ZoomMode := rvzmFullPage;
end;

procedure TFSRVPrint.btnPreviewClick(Sender: TObject);
begin
  SRVPrint1.Update;
end;

procedure TFSRVPrint.cbAutoUpdateClick(Sender: TObject);
begin
  SRVPrint1.AutoUpdate := cbAutoUpdate.Checked;
  btnPreview.Enabled := not cbAutoUpdate.Checked;
end;

procedure TFSRVPrint.srvprvwBeforePaint(Sender: TObject; ACanvas: TCanvas;
  ARect: TRect);
var
     hRGN : Cardinal;
     tmp : TRect;
begin
  if srvprvw.ZoomPercent = 100 then
    Exit;

  hRGN := CreateRectRgn(0, 0, srvprvw.Width, srvprvw.Height);
  SelectClipRgn(ACanvas.Handle, hRGN);

  ACanvas.Brush.Color := clWhite;
  ACanvas.FillRect(Bounds(0, 0, srvprvw.Width, srvprvw.Height));

  tmp := Rect(ARect.Left - 15, ARect.Top - 16, ARect.Left, ARect.Bottom + 16);
  ACanvas.StretchDraw(tmp, imgLeft.Picture.Graphic);

  tmp := Rect(ARect.Right, ARect.Top - 16, ARect.Right + 14, ARect.Bottom + 16);
  ACanvas.StretchDraw(tmp, imgRight.Picture.Graphic);

  tmp := Rect(ARect.Left - 14, ARect.Top - 16, ARect.Right + 14, ARect.Top);
  ACanvas.StretchDraw(tmp, imgTop.Picture.Graphic);

  tmp := Rect(ARect.Left - 14, ARect.Bottom, ARect.Right + 14, ARect.Bottom + 36);
  ACanvas.StretchDraw(tmp, imgBottom.Picture.Graphic);

  tmp := Rect((ARect.Left + ARect.Right - 30) div 2, ARect.Bottom,
               (ARect.Left + ARect.Right + 30) div 2, srvprvw.Height);
  ACanvas.StretchDraw(tmp, imgBottom2.Picture.Graphic);

  DeleteObject(hRGN);

  hRGN := CreateRectRgn(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
  SelectClipRgn(ACanvas.Handle, hRGN);
  DeleteObject(hRGN);
end;

procedure TFSRVPrint.FormResize(Sender: TObject);
begin
  srvprvw.ZoomMode := rvzmFullPage;
end;

end.
