Recent

Author Topic: Printing  (Read 11002 times)

Himie

  • Newbie
  • Posts: 2
Printing
« on: January 16, 2017, 05:57:34 am »
Hi Guys
I have had some experience with Delphi but new to Lazarus.  I am trying to print out to a HP laserjet printer with no success.  After having trouble printing from an array I have set up a temporary button which attempts to print a simple text file (just as a test to get it right).  It puts a page through the printer with no text on it.  Also does the same with a Canon inkjet printer.
The code is shown below and I have Printer4Lazarus in the Projects and have put Printers in the Uses entry.  It brings up the Printer dialog allowing me to select the correct printer and then prints the blank page.  I must be doing something stupid but I can't pick up what it is.  Thanks to anyone who can give me a pointer as to what to do.
The code I have is:

procedure TForm1.Button1Click(Sender: TObject);    //Temp Button
Var
  fName, mString: String;
  mTempFile: TextFile;
begin
  if PrintDialog1.Execute then begin    // work OK - allows choice of printer
    fName := 'TempStore.TXT';
    AssignFile(mTempFile,Fname);
    ReWrite(mTempFile);
    Writeln(mTempFile, 'This is a test for writing and printing');     // works OK - writes to file
    Reset(mTempFile);
    Readln(mTempFile, mString);

    showmessage(mString);      // This works OK - shows the text which means readln works OK

    Printer.BeginDoc;
      Printer.Canvas.TextOut(10,30,mString);    // This prints a blank page - no text shown
    Printer.EndDoc;
  end;
  CloseFile(mTempFile);
end;               

Thanks guys - you are champions

GAN

  • Sr. Member
  • ****
  • Posts: 370
Re: Printing
« Reply #1 on: January 16, 2017, 08:06:29 am »
Lazarus 2.0.8 FPC 3.0.4 Linux Mint Mate 19.3
Zeos 7̶.̶2̶.̶6̶ 7.1.3a-stable - Sqlite 3.32.3 - LazReport

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: Printing
« Reply #2 on: January 16, 2017, 08:46:16 am »
LazReport is only for using advanced printing like reports from database.
For simple printing uses this:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   MyFile: TextFile;
  4. begin
  5.   AssignPrn(MyFile);
  6.   Rewrite(MyFile);
  7.   Writeln(MyFile, 'Print this text');
  8.   System.CloseFile(MyFile);
  9. end;
  10.  
For more options look at this link.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Printing
« Reply #3 on: January 16, 2017, 10:03:03 am »
The simplest way in FPC is:
Code: Pascal  [Select][+][-]
  1. program printit;
  2. {$ifdef fpc}{$mode delphi}{$H+}{$endif}
  3. uses
  4.   printer; // not printers!!
  5. begin
  6.   writeln(lst,'Print some');  // lst is printer default device as TEXTFILE
  7. end.

In a GUI app it would be something like:
Code: Pascal  [Select][+][-]
  1. // add printer to the uses clause. Not printers...
  2. procedure TForm1.Button1Click(Sender: TObject);
  3. begin
  4.   if IsLstAvailable then
  5.     WriteLn(lst, 'Print something');
  6. end;    
  7.  
« Last Edit: January 16, 2017, 10:11:39 am by Thaddy »
Specialize a type, not a var.

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: Printing
« Reply #4 on: January 16, 2017, 10:16:57 am »
Mmmm, nobody can answer this for the Printer-object?
What if Himie wants to print the text somewhere on the middle of the paper?
Using lst is very basic... using LazReport is very advanced... using Printer.Canvas is the middle ground.

@Himie, If you take a magnifying glass you will see your text does get printed (in a very small letter font).
It could also be that 10,30 is just outside the printable margin of the paper (depending on your printer).

Try this
Code: Pascal  [Select][+][-]
  1. Printer.BeginDoc;
  2. Printer.Canvas.Font.Size := 14;
  3. Printer.Canvas.TextOut(200, 200, mString);
  4. Printer.EndDoc;
The coordinates depend on the resolution of your printer (which is in Printer.XDPI and Printer.YDPI).
« Last Edit: January 16, 2017, 10:20:06 am by rvk »

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Printing
« Reply #5 on: January 16, 2017, 10:31:30 am »
@rvk: OTOH all available formatting and redirection for writeln is available, so it is not THAT basic.. ;)  But you are right that the printer object is of course way more powerful and a report solution probably overkill.

@mangakissa: where is AssignPrn declared? In Delphi it is in printers, but in Lazarus it is not?
« Last Edit: January 16, 2017, 10:37:01 am by Thaddy »
Specialize a type, not a var.

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: Printing
« Reply #6 on: January 16, 2017, 10:35:03 am »
Yeah...
Code: Pascal  [Select][+][-]
  1. writeln;
  2. writeln;
  3. writeln;
  4. writeln;
  5. writeln;
  6. writeln('                          yipeee');
:D (or is there another way?)

And isn't the formatting dependent on type of printer?
Is the lst a "raw"-printer or does it somehow go through the canvas anyway? (I'm not sure)
If it's the first... what happens with actual real "Windows-printers"... yuk, yeah, they still exist :)
 

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Printing
« Reply #7 on: January 16, 2017, 10:37:45 am »
Add crt ;) or writeln(lst,',start,#10#10#10#10#9#9,'six lines, two tabs');

Yes, lst is a raw text device. A printer should treat it with a fixed font.Most printers do. Handy for tables and the like.
But I am fully aware of what you wrote. Note that e.g. Linux can also handle many windows printers nowadays. Or use CUPS.
« Last Edit: January 16, 2017, 10:49:33 am by Thaddy »
Specialize a type, not a var.

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printing
« Reply #8 on: January 16, 2017, 01:26:21 pm »
Over the past week I've also had to come to terms with the facilities in Printer4Lazarus and, I think, very successfully.

Because I always print to a .PDF file and my 'default' printer is set to that I haven't bothered with printer selection (as yet).

I've created a procedure called 'PrintLine' which takes a number of arguments, viz :

Code: Pascal  [Select][+][-]
  1. const
  2.   FontList  : array[1..10] of string[20] = ('ZapfCalligr BT',
  3.                                             'Optima',
  4.                                             'Windsor BT',
  5.                                             'Windsor Lt BT',
  6.                                             'CroissantD',
  7.                                             'CopprplGoth BT',
  8.                                             'Arial',
  9.                                             'Dauphin',
  10.                                             'Futura Md BT',
  11.                                             'Symbol');
  12.   DPM         : single = 23.62204724;
  13.  
  14. [...]
  15.  
  16. procedure PrintLine(X,Y :single; S : String; FN : byte; Col : word; PT : byte );
  17. Var
  18.   Ht       : byte;
  19. begin
  20. //                X = H Pos in mm, Y - V Pos in mm  S - Text  FN = FontList Index Col = Colour   P Point Size
  21.   with printer do
  22.     begin
  23.       Canvas.Font.Name := FontList[FN];
  24.       Canvas.Font.Size := PT;
  25.       Canvas.Font.Color := Col;
  26.       Ht := Abs(Canvas.TextHeight('I'));
  27.       Canvas.TextOut(Trunc(X*DPM),Trunc(Y*DPM - Ht),S);
  28.       if Y > prBottom then
  29.         prPageEnd := true;
  30.     end;
  31.   end;

As you can see, I've also declared an Array of FontList which allows 'on the fly' selection of typeface, and a constant - DPM - (Dots Per MM) since I find it more convenient to specify the position on page in mm.

In my case, using CutePDF set at 600dpi, the DPM setting is 23.62204724. 

Again, because I want to specify the position at the base line of the text, I use [Ht] to calculate the height of the text string being output and take that away from the specified position because 'TextOut' expects the location to be the top of the string.

I haven't yet implemented a 'FontStyle' but that is on the 'things to do' list.

To print Currency Values I've also created a PrintVal procedure to print with right alignment, viz:

Code: Pascal  [Select][+][-]
  1. procedure PrintVal(V : single; X,Y : word; PT : byte);
  2. Var
  3.   Col : word;
  4.   S   : string[10];
  5.   W   : single;
  6. begin
  7.   Str(Abs(V):8:2,S);
  8.   StripLeadingSpace(S);
  9.   if V < 0 then
  10.     begin
  11.       Col := Red;
  12.       S :='£('+S;
  13.     end
  14.   else
  15.     begin
  16.       Col := clBlack;
  17.       S   := '£'+S;
  18.     end;
  19.   Printer.Canvas.Font.Size :=PT;
  20.   W := Abs(Printer.Canvas.TextWidth(S)/DPM);
  21.   PrintLine(X-W,Y,S,1,Col,PT);
  22.   if V < 0 then
  23.     PrintLine(X,Y,')',1,Col,PT);
  24. end;

This also handles the £(20.00) format for negative values discussed in another thread.

These procedures are called from other procedures which do the basic calls which are necessary, the basics of one of which is :

Code: Pascal  [Select][+][-]
  1. procedure TForm1.PrintSuppListClick(Sender: TObject);
  2. begin
  3.   PrintSuppList.Caption := 'PRINTING';
  4.   InitReport;
  5.   Report := 2;
  6.   with Printer do
  7.    try
  8.      BeginDoc;
  9.      PrintReportHeader;
  10.  
  11. //    Print details .........  
  12.      
  13.      if prPageEnd then
  14.        StartNewPage;
  15.     finally
  16.      EndDoc;
  17.    end;
  18.   sleep(1500);
  19.   PrintSuppList.Caption := 'Print Supplier List';
  20. end;

Which you can see also tells the user that 'PRINTING' is being done - the Sleep(1500) simply keeps that notice visible for the time it takes for the printer dialogue to become active  :)     otherwise the user might think that the command hadn't been actioned.

« Last Edit: January 16, 2017, 01:35:18 pm by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

mangakissa

  • Hero Member
  • *****
  • Posts: 1131
Re: Printing
« Reply #9 on: January 16, 2017, 03:20:39 pm »
@mangakissa: where is AssignPrn declared? In Delphi it is in printers, but in Lazarus it is not?
I thought fpc is compatible on using Assignprn in Delphi. I was wrong. My apologies.
Lazarus 2.06 (64b) / FPC 3.0.4 / Windows 10
stucked on Delphi 10.3.1

Himie

  • Newbie
  • Posts: 2
Re: Printing
« Reply #10 on: January 16, 2017, 04:42:28 pm »
big thank you to all who took the time and effort to reply.  And yes, it was as you described rvk - setting the font size and the other coordinates solved the problem.  I spent about 2 days researching and trying to get that right and am most appreciative.
BTW for reference for others reading responses, it is 'printers' and not 'printer' that goes in the uses clause.  Form1.print does not work in Lazarus (it does in Delphi) and Assignprn is not implemented in Lazarus (is in Delphi).
Have a great 2017

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Printing
« Reply #11 on: January 17, 2017, 12:30:14 pm »
it is 'printers' and not 'printer' that goes in the uses clause.
You musunderstood. If you use my old school  lst/writeln method the unit is printer without S. If you use other methods, object oriented, with the printer class, the unit is printers, with the S.
« Last Edit: January 17, 2017, 12:32:26 pm by Thaddy »
Specialize a type, not a var.

 

TinyPortal © 2005-2018