Recent

Author Topic: Printer Paper Orientation  (Read 2312 times)

J-G

  • Hero Member
  • *****
  • Posts: 953
Printer Paper Orientation
« on: August 14, 2022, 08:55:51 pm »
I've used Printers4Lazarus to great effect in the past but never had the need to change from 'Portrait' to 'View'. With my current Project this has become necessary so I've reviewed the Wiki page 'Using the printer' along with the 'Printers' Unit. The former makes no reference to changing the orientation and although I do find a reference to SetOrientation (and Get...) in the Unit, I'm not having any joy in impementing a change.

Using the 'auto-complete' facility, I can access the property - Printer.SetOrientation - which requires a 'Value' which I assume may be 0 or 1 or something else entirely, but the compiler returns an 'Identifier not found' for SetOrientation() or a wierd (to me) 'Syntax error, "EXCEPT" expected but "(" found' if I reduce that to 'Orientation'.

The first error seems most peculiar when auto-complete offers the property.

Whilst I would be interested (academically) in the reasons behind the error messages, what I really want to know is how do I set the paper orientation?

A secondary question though is  how can I invoke the Printer Set Up Dialogue or the Page Set Up Dialogue?  both of which I have placed on the form but the [Events] associated with them don't have [OnClick]  -  I have to assume that a third party component (with [On Click]) is needed but can't yet fathom how I can link the two.

A positive answer to this secondary question may well mean that the first question becomes irrelevant!
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Printer Paper Orientation
« Reply #1 on: August 14, 2022, 09:20:12 pm »
Code: Pascal  [Select][+][-]
  1. uses
  2.   Printers;
  3.  
  4. procedure TForm1.Button1Click(Sender: TObject);
  5. begin
  6.   //run printer dialog
  7.   ShowMessage('Current printer: ' + Printer.PrinterName);
  8.   if PrintDialog1.Execute then
  9.     ShowMessage('Printer changed to: ' + Printer.PrinterName + #13#10 +
  10.       ' and number of copies set to: ' + IntToStr(Printer.Copies));
  11. end;
  12.  
  13. procedure TForm1.Button2Click(Sender: TObject);
  14. const
  15.   poarr: array [TPrinterOrientation] of String = ('portait', 'landscape', 'reverse portait', 'reverse landscape');
  16. begin
  17.   //run page setup dialog
  18.   ShowMessage('Current orientation: ' + poarr[Printer.Orientation]);
  19.   if PageSetupDialog1.Execute then
  20.     ShowMessage('Orientation changed to: ' + poarr[Printer.Orientation] + #13#10 +
  21.       ' and paper size: ' + Printer.PaperSize.PaperName);
  22. end;
  23.  
  24. procedure TForm1.Button3Click(Sender: TObject);
  25. begin
  26.   //change paper orientation
  27.   if Printer.Orientation = poPortrait then
  28.     Printer.Orientation := poLandscape
  29.   else
  30.     Printer.Orientation := poPortrait;
  31. end;          
« Last Edit: August 14, 2022, 09:23:54 pm by paweld »
Best regards / Pozdrawiam
paweld

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printer Paper Orientation
« Reply #2 on: August 14, 2022, 11:06:33 pm »
!! @ paweld !!

On opening your reply I was at first somewhat taken aback

- just code without explanation ??

... but it didn't take me long to appreciate that it is a most succinct but fullsome reply providing all the answers I could want !

I'll have to do some testing and 'adjustment' but that's all the better since (hopefully) I'll learn so much more.

Many thanks.
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Printer Paper Orientation
« Reply #3 on: August 14, 2022, 11:17:37 pm »
Hi @J-G,My written English is not very good, and often sample code with short comments will help you understand more than the description.
Best regards / Pozdrawiam
paweld

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printer Paper Orientation
« Reply #4 on: August 15, 2022, 03:04:17 am »
Hi @J-G,My written English is not very good, and often sample code with short comments will help you understand more than the description.

It's vastly superior to my Polish!!   :D

I haven't done much work on it yet, I've spent most of this evening working out how to show a 'Print Preview'  -  just showing the size of the final image within and A4 outline --  which I think I cracked about half-an-hour ago.  It can determine whether to use Portrait or View Orientation so will be used when I come to code the actual Print routine.

FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Printer Paper Orientation
« Reply #5 on: August 15, 2022, 09:12:33 am »
Instead of writing print and preview support from scratch, you can use ready-made components, such as fpReport. Sample in attachement.
Best regards / Pozdrawiam
paweld

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printer Paper Orientation
« Reply #6 on: August 15, 2022, 08:28:17 pm »
Instead of writing print and preview support from scratch, you can use ready-made components, such as fpReport. Sample in attachement.
Hmmm...  I don't think so.

When I selected a 180k .png file it took over a minute (I'm guessing :) ) to show a blank 'preview' --- the 'image' appeared a little while later but 'draging' the preview about the screen was equally lethargic and even stopped all other mouse activity.

My 'preview' only needs to show the area that the final image will take up and it has to be 'dynamic' - ie. changing with each minor modification to the data.

The attached ScreenGrab shows two results - one Portrait the other View -  I've added the yellow box after taking the grab to indicate the part of the display that will actually be sent to the printer. The preview is just a TMemo on a TPanel but I may change that and draw a box on the panel since I don't see a way to add a border to the TMemo. In real life the memo outline can be seen but it's rather weak.

I suspect that trying to understand fpReport would take me vastly longer than writing the Print Code from scratch -- and of course I'll understand my own code  ::)
« Last Edit: August 15, 2022, 08:42:11 pm by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printer Paper Orientation
« Reply #7 on: August 16, 2022, 06:17:06 pm »
I'm somewhat further forward, having three operational buttons to [Print], [Page Setup] & [Select Printer] but there is still an action which is eluding me.

I'm using the code :
Code: Pascal  [Select][+][-]
  1. procedure TForm1.PrintImgClick(Sender: TObject);
  2.   procedure PrintDescription;
  3.   begin
  4.     PrintCentrePage(10,Desc,1,16,1);
  5.   end;
  6.  
  7.   procedure PrintTooth;
  8.   begin
  9.  
  10.   end;
  11.  
  12. begin
  13.   with Printer do
  14.    try
  15.      BeginDoc;
  16.      if P_Orient = 'P' then
  17.        Orientation := poPortrait
  18.      else
  19.        Orientation := poLandscape;
  20.  
  21.      PrintDescription;
  22. //     PrintTooth;
  23.    finally
  24.      EndDoc;
  25.    end;
  26. end;
to create the print   -  I haven't yet coded 'Print Tooth' as you can see, I'm just testing that the 'Description' prints at top centre which it does IF the Page Setup is in the correct orientation. That is lines 15 to 19 have no effect.

Using that same code in the [Page Setup] proc  - - - -
Code: Pascal  [Select][+][-]
  1. procedure TForm1.SetupClick(Sender: TObject);
  2. begin
  3.   if P_Orient = 'P' then
  4.     Printer.Orientation := poPortrait
  5.   else
  6.     Printer.Orientation := poLandscape;
  7.  
  8.   PageSetup.Execute;
  9. end;

... correctly sets the orientation but only if I use that button each time. I would have expected that to be sufficient to make the approriate change in Code.  It seems wrong to need to insert 'PageSetup.Execute;' at Line 20 which would open the Dialogue every time.

It's useful to have the option to change the page size etc. using the [Page Setup] but it surely shouldn't be necessary to enter that dialogue explicitly when there is the facility to set 'Orientation' via code.

I've tested [Select Printer]  - ie. I can change the printer in use -- and that works   -  as long as the orientation has been set with similar code in the [Select Printer] Proc.

I must be missing a 'magiic bullet' of some kind but can't see what or where yet  :(





FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Printer Paper Orientation
« Reply #8 on: August 16, 2022, 10:19:10 pm »
Perhaps the attached example will help you.
Best regards / Pozdrawiam
paweld

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printer Paper Orientation
« Reply #9 on: August 17, 2022, 02:54:28 am »
Perhaps the attached example will help you.
Thanks for your efforts @paweld. That's certainly an interesting program but I don't think it addresses my problem.

I work out whether the orientation needs to be Portrait or Landscape according to the height & width of the gear tooth  -  the object to be plotted  -  without overtly selecting the orientaion by use of a [button].

It seems reasonable (to me) that using the Printer.Orientaion := poXXXXXX  should do just that and I can't see what I need to do to make that so.

Working on a bitmap and selecting any part thereof is one thing but you still set the orientation by use of the RadioButtons.  If you determined the orientation according to the shape selected  that is; if the selection is taller than it is wide then the orientation should be set to poPortrait but if the selection is wider than it is tall then the orientation should be poLandscape -  if you could then set it without recourse to the RadioButtons you would be much closer to my problem.

FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Printer Paper Orientation
« Reply #10 on: August 17, 2022, 07:03:30 am »
Before generating a preview / printout, you need to check the ratio of the width of the image (selected area) to its height - if the width is greater than the height then you set the horizontal orientation, otherwise vertical.
Modified version attached.
Best regards / Pozdrawiam
paweld

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printer Paper Orientation
« Reply #11 on: August 17, 2022, 08:49:33 am »
Before generating a preview / printout, you need to check the ratio of the width of the image (selected area) to its height - if the width is greater than the height then you set the horizontal orientation, otherwise vertical.
Modified version attached.
Sorry @paweld, we still have a misunderstanding.  What I need is a reason why the orientation isn't changed without ME setting the orientation.

You say "then you set the horizontal orientation"  (my emphasis),  I nead a means by which the orientation is set without recourse to a secondary component ([TButton],[Radio Button]...). I can already manually set the orientation by invoking the [Page Setup] button and it is correctly set using the If...Then...Else construct but that doesn't do the job without calling the dialogue.

 
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Printer Paper Orientation
« Reply #12 on: August 17, 2022, 09:51:00 am »
@J-G: If "Auto" is selected in RagioGroup then the program, based on the size of the image, checks what the page setting should be, and this function does it:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.SetAutoPageOrientation;
  2. var
  3.   whscale: Double;
  4. begin
  5.   if (Image1.Picture.Width = 0) or (Image1.Picture.Height = 0) then
  6.   begin
  7.     Printer.Orientation := poPortrait;
  8.     exit;
  9.   end;
  10.   if RadioGroup1.ItemIndex = 0 then   //if cheched auto page orientation
  11.   begin
  12.     if (FSelection.Width = 0) or (FSelection.Height = 0) then  //FSelection - is TRect with selection area
  13.       whscale := Image1.Picture.Width / Image1.Picture.Height
  14.     else
  15.       whscale := abs(FSelection.Width) / abs(FSelection.Height);
  16.     if whscale > 1 then
  17.       Printer.Orientation := poLandscape
  18.     else
  19.       Printer.Orientation := poPortrait;
  20.   end;
  21. end;              
« Last Edit: August 17, 2022, 09:58:42 am by paweld »
Best regards / Pozdrawiam
paweld

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: Printer Paper Orientation
« Reply #13 on: August 17, 2022, 11:05:53 am »
Thanks for your continued patience @paweld but I don't have (and don't want) a [RadioGroup] so can't set that to 'Auto'.

I've done some more testing and find another 'issue' - though whether this has any bearing on the problem is debateable -  I have a .PDF printer set as the 'Default' and create the filename in a string called F_Name - works as expected and is set to Printer .Title thus :
Code: Pascal  [Select][+][-]
  1.  
  2. [...]
  3. with Printer do
  4.    try
  5.      BeginDoc;
  6.      Title := F_Name+'.PDF';
  7.      if P_Orient = 'P' then
  8.        Orientation := poPortrait
  9.      else
  10.        Orientation := poLandscape;
  11. [...]
  12.  
However the first time I click [Print] the filename is blank. If I [Cancel] the print and immediately click  [Print] again, the filename is shown ????

Further, if I change a parameter - which creates a new F_Name - the filename shown in the [Print] dialogue is the previous one !!! 

Stepping through the code, I can confirm that 'Printer.Title' is correctly set to F_Name at line 6 of the code snippet above and that 'Printer.Orientation' is also correctly selected in the If...Then...Else section.

« Last Edit: August 17, 2022, 11:12:10 am by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Printer Paper Orientation
« Reply #14 on: August 17, 2022, 12:15:03 pm »
Attached to the previous post are the modified sources from which I removed the RadioGroup control.

In Printer.Title you specify the name of the report, not the name of the target PDF file.
Look in the attached example, in my case the report title is passed to the PDF printer every time.
Best regards / Pozdrawiam
paweld

 

TinyPortal © 2005-2018