Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Paginate printer function 2

Status
Not open for further replies.

lespaul

Programmer
Feb 4, 2002
7,083
US
So I found this print StringGrid function that works ( but it doesn't paginate...Is there an easy way to tell if I'm at the bottom of a page and start a new one? I can think of some hard ways to tell, but I'd like to get some outside opinions!

Any help appreciated!

Les
Code:
procedure TfrmRecordPayment.PrintGrid(sGrid: TStringGrid; sTitle: string);
var
  X1, X2: Integer;
  Y1, Y2: Integer;
  TmpI: Integer;
  F: Integer;
  TR: TRect;
begin
  Printer.Title := sTitle;
  Printer.BeginDoc;
  Printer.Canvas.Pen.Color  := 0;
  Printer.Canvas.Font.Name  := 'Times New Roman';
  Printer.Canvas.Font.Size  := 12;
  Printer.Canvas.Font.Style := [fsBold, fsUnderline];
  Printer.Canvas.TextOut(0, 100, Printer.Title);
  for F := 1 to sGrid.ColCount - 1 do
  begin
    X1 := 0;
    for TmpI := 1 to (F - 1) do
      X1 := X1 + 5 * (sGrid.ColWidths[TmpI]);
    Y1 := 300;
    X2 := 0;
    for TmpI := 1 to F do
      X2 := X2 + 5 * (sGrid.ColWidths[TmpI]);
    Y2 := 450;
    TR := Rect(X1, Y1, X2 - 30, Y2);
    Printer.Canvas.Font.Style := [fsBold];
    Printer.Canvas.Font.Size := 10;
    Printer.Canvas.TextRect(TR, X1 + 50, 350, sGrid.Cells[F, 0]);
    Printer.Canvas.Font.Style := [];
    for TmpI := 1 to sGrid.RowCount - 1 do
    begin
      Y1 := 150 * TmpI + 300;
      Y2 := 150 * (TmpI + 1) + 300;
      TR := Rect(X1, Y1, X2 - 30, Y2);
      Printer.Canvas.TextRect(TR, X1 + 50, Y1 + 50, sGrid.Cells[F, TmpI]);
    end;
  end;
  Printer.EndDoc;
end;
 
Printer.PageHeight and Printer.PageWidth.

If you're doing uniform text (I see you're not), then the number of lines on the page would simply be Printer.PageHeight div "TextHeight()". Otherwise, you can keep track of number of pixels + spacing between words used and compare it to Printer.PageHeight.

Not super-easy but doable enough I would think.
 
what would I need to do to use uniform text?

Like I said, I copied this directly from the website I linked above. I pasted it in my unit and except for not having page breaks, it does what I need.

Thanks!
Leslie
 
what would I need to do to use uniform text?

What I meant was text that would take up a uniform height. Like not changing font, size, or style. But adding pixel size and comparing with Printer.PageHeight should be simple enough too (that's what the example in this book I consulted does).
 
I see, I thought you meant there was a "uniform text" type!

I can change the font, size and style to be uniform, that's not a problem. Can you provide some of the example from the book you're referring to?

Thanks!

Leslie
 
The example doesn't quite relate. I decided, though, to play around a little bit and get a printer demo going (educational purposes again, I want to try to get it as fully featured as I can). I'll post the "print file" button event of that below.

Code:
var
  i: integer;
  linesize: integer;
  textsize: integer;
  pagesize: integer;
  ppiv, ppih: integer;
begin
  if PrintDialog1.Execute then
     begin
       Printer.BeginDoc;
       { get size of printer pixels per inch for horizontal and vertical
         margins }
       ppih := GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSX);
       ppiv := GetDeviceCaps(Printer.Canvas.Handle, LOGPIXELSY);
       with Printer.Canvas.Font do
         begin
           Size := Memo1.Font.Size;
           Name := Memo1.Font.Name;
           Style := Memo1.Font.Style;
           Color := Memo1.Font.Color;
           Charset := Memo1.Font.Charset;
           Pitch := Memo1.Font.Pitch;
         end;
       pagesize := Printer.PageHeight;
       StatusLabel.Caption := 'Printing Page ' + IntToStr(Printer.PageNumber);
       linesize := ppiv;
       for i := 0 to Memo1.Lines.Count-1 do
         begin
           textsize := Printer.Canvas.TextHeight(Memo1.Lines.Strings[i]);
           if linesize+textsize+ppiv >= pagesize then
             begin
               Printer.NewPage;
               StatusLabel.Caption := 'Printing Page ' + IntToStr(Printer.PageNumber);
               linesize := ppiv;
             end;
            Printer.Canvas.TextOut(ppih, linesize, Memo1.Lines.Strings[i]);
            inc(linesize, textsize);
         end;
       Printer.EndDoc;
       StatusLabel.Caption := 'File Printed.';
     end;
end;

Notes:
1. Still working on it, so don't be surprised if you find a minor problem or two. I know the paging works fine, though, which was what you were interested in to begin with.
2. Basic idea of the whole app: Load text file into memo box, button is there to call the font dialog to change the font of the memo box. The memobox font settings are copied to the printer when the file is printed from the memo box.
3. ppih and ppiv are pixels per inch horizontal and vertical. The logic has 1 inch margins on the left, top, and bottom. However, the margin on the page will be 1 inch + whatever the natural margins are for the printer.
4. If you notice, I use "TextHeight" for the spacing of the text on the printer canvas. As long as you do that and keep track of how much canvas is on the page, you should be fine to do whatever you want with the text attributes, and be able to know when to trigger a new page.

Hope that helps.
 
Wow! I didn't know there was a Printer.NewPage call! that's cool. In other documents I Start and End the doc for each call. Learn something new everyday!

I'll try and mess around with this and see what I can get!

Leslie
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top