View Issue Details

IDProjectCategoryView StatusLast Update
0003079JEDI VCL00 JVCL Componentspublic2005-07-12 04:20
ReporterwaskolAssigned Touser72 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.00 
Target VersionFixed in Version3.10 
Summary0003079: Pages of TJVPreviewControl sent to the printer with TJvPreviewPrinter do not print with the good margins
Description1) you need 2 controls on a form, namely :
a) JVPreviewControl1 be a TJVPreviewControl
b) JvPreviewPrinter1 be a TJvPreviewPrinter with
    JvPreviewPrinter1.PrintPreview:=JVPreviewControl1;

1) Create a page with the JVPreviewControl1.Add
2) Build your page with the JVPreviewControl1.OnAddPage event

--> First note :
the PrintRect variable has the dimensions of the Printer Physical Page and the PageRect variable is bigger than it should be, precisely :
- PrintRect:=(0,0,PhysicalWidth, PhysicalHeight)
- PageRect:=(-OffsetLeft,-OffsetTop,PhysicalWidth+OffsetRight, PhysicalHeight+OffsetBottom)

--> It shoul be :
- PageRect:=(0,0,PhysicalWidth, PhysicalHeight)
- PrintRect:=(+OffsetLeft,+OffsetTop,PhysicalWidth-OffsetRight, PhysicalHeight-OffsetBottom)

2) Print your page with JvPreviewPrinter1.Print :
Margins were not taken into account... (i.e you get a full page printing without the margins);
Additional InformationI suggest TWO modifications in the JvPrvwDoc.pas (version 1.35) file :
1) In the "function TJvCustomPreviewControl.DoAddPage(AMetaFile: TMetafile; PageIndex: Integer): Boolean;" method :

Instead of :
      Dec(APageRect.Left, OffsetLeft);
      Dec(APageRect.Top, OffsetTop);
      Inc(APageRect.Right, OffsetRight);
      Inc(APageRect.Bottom, OffsetBottom);

You should have :
     Inc(APrintRect.Left, OffsetLeft);
     Inc(APrintRect.Top, OffsetTop);
     Dec(APrintRect.Right, OffsetRight);
     Dec(APrintRect.Bottom, OffsetBottom);

2) In the "procedure TJvCustomPreviewControl.DrawPreview(PageIndex: Integer;APageRect, APrintRect: TRect);" method :

Instead of :
  FBuffer.Canvas.StretchDraw(APrintRect, Pages[PageIndex]);

You should have :
  FBuffer.Canvas.StretchDraw(APageRect, Pages[PageIndex]);

And everything should work fine...
Notice : correction N°1 does not work if correction N°2 was not done too !
TagsNo tags attached.

Activities

2005-07-06 07:19

 

JvPrvwDoc.zip (12,426 bytes)

waskol

2005-07-06 07:26

reporter   ~0007530

I have just uploaded the JvPrvwDoc.pas file in its latest version (1.35) with my suggested corrections.

- The original code was commented out
- The corrections are enclosed between two "//WA Correction" comments.
- The version of the original file was not modified at all, I let the original Author do do all the official corrections if he feels doing it.

Nota : Thanks peter for those good printing components, they are very usefull :)

anonymous

2005-07-06 16:38

viewer   ~0007531

The two corrections above are necessary but are not enough to provide good printing of the documents within the printable area of the printer page.
In effect, if you try the components with the two corrections here you will still notice that even if the Print Preview is good, the printed document is somewhat shifted with towards the bottom right. This is explained by the fact that the Pages deigned by the user and that are recorded in the PreviewControl are printed to the printer canvas at coordinates (0,0) (have a look inside the code of the TJVPreviewControl.PrintRange method.

A few correction have to be made inside this method in order to print the Pages at coordinates (-PHYSICALOFFSETX?--PHYSICALOFFSETY) of the printer canvas.
In order to get those values, it is necessary to get the Device Capabilities of the "APrinter" object wich implies to know its handle.

That leads to a new method for the IJVPrinter Interface called GetHandle, properly implemented in the TVPrintPreview class.

Updates are ready at my work, everything is printing nicely :)
Since I am at home, please wait for tomorrow in order to get final updates.

Damn, those Printing components are terrific, and you can combine them with to other components of the JVCL : TJVPageSetup and TJVPageTitle (or a thing like that) wich are lost in the JVDialogs tab of the component palette.

waskol

2005-07-07 01:18

reporter   ~0007534

As promised in my last post, here are the last corrections i suggest :

1) Correction of the IJvPrinter interface in JVPrvwDoc.pas:

Instead of :
  IJvPrinter = interface
    ['{FDCCB7CD-8DF7-48B9-9924-CE439AE97999}']
    procedure SetTitle(const Value: string);
    function GetTitle: string;
    procedure BeginDoc;
    procedure EndDoc;
    procedure NewPage;
    procedure Abort;
    function GetAborted: Boolean;
    function GetCanvas: TCanvas;
    function GetPageWidth: Integer;
    function GetPageHeight: Integer;
    function GetPrinting: Boolean;
  end;

I suggest :
  IJvPrinter = interface
    ['{FDCCB7CD-8DF7-48B9-9924-CE439AE97999}']
    procedure SetTitle(const Value: string);
    function GetTitle: string;
    procedure BeginDoc;
    procedure EndDoc;
    procedure NewPage;
    procedure Abort;
    function GetAborted: Boolean;
    function GetCanvas: TCanvas;
    function GetPageWidth: Integer;
    function GetPageHeight: Integer;
    function GetPrinting: Boolean;
    //WA 2nd correction
    function GetHandle:HDC;
    //WA 2nd correction
  end;

2) Implementtion of the GetHandle method in JVPrvwRender.pas :

in the protected clause of the TJvPreviewPrinter class we declare
    function GetHandle:HDC;

it is implemented like this :

function TJvPreviewPrinter.GetHandle: HDC;
begin
  CheckPrinter;
  Result := FPrinter.Handle;
end;
(see attached files)

2) Correction of the TJvCustomPreviewControl.PrintRange method (please see attached files) :

a) We add some variables in the local declaration clause :
   PrinterPhysicalOffsetX,PrinterPhysicalOffsetY:cardinal;

b) Instead of :
   begin
     if (APrinter = nil) or APrinter.GetPrinting then
       Exit;
     if StartPage < 0 then
     ....
  
   we write :
   begin
     if (APrinter = nil) or APrinter.GetPrinting then Exit;
     //WA Correction
     PrinterPhysicalOffsetX:=GetDeviceCaps(APrinter.GetHandle, PHYSICALOFFSETX);
     PrinterPhysicalOffsetY:=GetDeviceCaps(APrinter.GetHandle, PHYSICALOFFSETY);
     //WA Correction

c) Everywhere in the procedure, when it is written :
    
     APrinter.GetCanvas.Draw(0, 0, Pages[J]);

   I suggest instead :
     //WA Correction
     APrinter.GetCanvas.Draw(-PrinterPhysicalOffsetX, -PrinterPhysicalOffsetY, Pages[J]);
     //WA Correction
   
I hope that you will accept my corrections, with those everything is printing nicely for me.

The files attached here are the latest versions of the files that are recorded in the CVS, amended with my corrections :
- JVPrvwRender.pas : version 1.28
- JVPrvwDoc.pas : version 1.35

I don't know if I am granted to post some new versions of those files to the CVS nor how to do it, so I would be glad that the original author could do it :)

2005-07-07 01:23

 

JvPrvwDoc v135 amanded.zip (12,547 bytes)

2005-07-07 01:24

 

JvPrvwRender v128 amended.zip (6,473 bytes)

waskol

2005-07-11 01:12

reporter   ~0007543

Last edited: 2005-07-11 01:13

Please, could you consider issue solved and update changes to the CVS ? (not much work to do here ;) )

Thxs a lot.

waskol

2005-07-11 03:02

reporter   ~0007545

Last edited: 2005-07-11 04:54

Four more bugs to correct in JvPrvwDoc.pas :

Instead of :
function TJvDeviceInfo.InchToXPx(Inch: Single): Integer;
begin
  Result := Round(Inch * LogPixelsY);
end;

function TJvDeviceInfo.InchToYPx(Inch: Single): Integer;
begin
  Result := Round(Inch * LogPixelsX);
end;

function TJvDeviceInfo.XPxToMM(Pixels: Integer): Single;
begin
  Result := XPxToInch(Pixels) / 25.4;
end;

function TJvDeviceInfo.YPxToMM(Pixels: Integer): Single;
begin
  Result := YPxToInch(Pixels) / 25.4;
end;

1) There is a X/Y inversion in the first two functions
2) There is an inconsistency in the dimensions since you should have
   [result in MM] := [YPxToInch in Inches] * [25.4 in MM/Inches]
      
   
As a result, we should have :
function TJvDeviceInfo.InchToXPx(Inch: Single): Integer;
begin
  Result := Round(Inch * LogPixelsX);
end;

function TJvDeviceInfo.InchToYPx(Inch: Single): Integer;
begin
  Result := Round(Inch * LogPixelsY);
end;

function TJvDeviceInfo.XPxToMM(Pixels: Integer): Single;
begin
  Result := XPxToInch(Pixels) * 25.4;
end;

function TJvDeviceInfo.YPxToMM(Pixels: Integer): Single;
begin
  Result := YPxToInch(Pixels) * 25.4;
end;

I did not update this one in the files i posted, please can you do that too ?

waskol

2005-07-12 00:49

reporter   ~0007550

New files attached :
- Suggested JvPrvwDoc v1.36
- Suggested JvPrvwRender v1.29

The code is clean, versioning has been updated in the files : both are ready to be posted on cvs.

2005-07-12 00:50

 

JvPrvwRender v1.29.zip (6,341 bytes)

2005-07-12 00:52

 

JvPrvwDoc v1.36.zip (12,266 bytes)

waskol

2005-07-12 02:34

reporter   ~0007551

New versions of TJvPreviewRenderRichEdit and TJvPreviewRenderJVRichEdit (See attached file : JvPrvwRender v1.30.zip)

Bugs corrections lead to other bug correction :
Since TJVPreviewControl, TJvPreviewPrinter, TJvCustomPreviewControl and TJvDeviceInfo are working fine now, I propose some new versions of TJvPreviewRenderRichEdit and TJvPreviewRenderJVRichEdit that print well fitted in the margins.

In the procedures TJvPreviewRenderRichEdit.DoAddPage and TJvPreviewRenderJvRichEdit.DoAddPage,
Instead of :
...
if IsRectEmpty(RichEdit.PageRect) then
    begin
      Range.rc.Right:=(PrintRect.Right-PrintRect.Left)*cTwipsPerInch div LogX;
      Range.rc.Bottom:=(PrintRect.Bottom-PrintRect.Top)*cTwipsPerInch div LogY;
    end
...

It should be :
...
if IsRectEmpty(RichEdit.PageRect) then
    begin
      Range.rc.Left :=PrintRect.Left*cTwipsPerInch div LogX;
      Range.rc.Top := PrintRect.Top * cTwipsPerInch div LogY;
      Range.rc.Right := PrintRect.Right * cTwipsPerInch div LogX;
      Range.rc.Bottom := PrintRect.Bottom * cTwipsPerInch div LogY;
    end
...

2005-07-12 02:35

 

JvPrvwRender v1.30.zip (6,343 bytes)

waskol

2005-07-12 03:08

reporter   ~0007552

Note to the admins :
I am so sorry, I just saw the reply that obones did to my post on the newsgroup...
I just understood that it was a very bad idea to have versioned the files I attached since the CVS does it by itself.

so, what must be done here is to becarefull before posting the new files to the cvs : please do not take into account the lines wich are like that :
// $Id: JvPrvwRender.pas,v 1.30 2005/07/12 11:12:30 waskol Exp $
and like that :
// $Id: JvPrvwDoc.pas,v 1.36 2005/07/12 09:15:00 waskol Exp $

Remember, the last versions with all the fixes are in
- "JvPrwDoc v1.36.zip", wich still should be a modified v1.35, and
- "JvPrvwRender v1.30.zip", wich still should be a modified v1.28

Sorry again for that mess...

user72

2005-07-12 04:20

  ~0007553

Updated in CVS. Thanks!

Issue History

Date Modified Username Field Change
2005-07-06 06:40 waskol New Issue
2005-07-06 07:19 waskol File Added: JvPrvwDoc.zip
2005-07-06 07:26 waskol Note Added: 0007530
2005-07-06 16:38 anonymous Note Added: 0007531
2005-07-07 01:18 waskol Note Added: 0007534
2005-07-07 01:23 waskol File Added: JvPrvwDoc v135 amanded.zip
2005-07-07 01:24 waskol File Added: JvPrvwRender v128 amended.zip
2005-07-11 01:12 waskol Note Added: 0007543
2005-07-11 01:13 waskol Note Edited: 0007543
2005-07-11 03:02 waskol Note Added: 0007545
2005-07-11 04:54 waskol Note Edited: 0007545
2005-07-12 00:49 waskol Note Added: 0007550
2005-07-12 00:50 waskol File Added: JvPrvwRender v1.29.zip
2005-07-12 00:52 waskol File Added: JvPrvwDoc v1.36.zip
2005-07-12 02:34 waskol Note Added: 0007551
2005-07-12 02:35 waskol File Added: JvPrvwRender v1.30.zip
2005-07-12 03:08 waskol Note Added: 0007552
2005-07-12 04:20 user72 Status new => resolved
2005-07-12 04:20 user72 Resolution open => fixed
2005-07-12 04:20 user72 Assigned To => user72
2005-07-12 04:20 user72 Note Added: 0007553