Forum > Beginners

Printing a Timage picture

(1/2) > >>

woodguy:
I'm posting this in the beginners section - if it should be elsewhere mods can feel free to move it.

I've created an application, one feature of which is the ability to print a preview image displayed in a Timage.  This is the relevant code:

var
    p_rect:trect;
    Scale:      Integer;
    myprinter:tprinter;
  const
    OriginX = 175;
    OriginY = 175;

  begin
    myprinter:=printer;
    Scale := Min(myPrinter.PageWidth div image1.picture.graphic.Width, myPrinter.PageHeight div image1.picture.graphic.Height);

    P_rect:=rect(OriginX, OriginY, OriginX + (image1.picture.graphic.Width  * Scale),OriginY + (image1.picture.graphic.Height * Scale));

    if PrintDialog1.Execute then
    begin
      Myprinter.BeginDoc;

      try
        //myprinter.Canvas.StretchDraw(P_rect,image1.picture.graphic);
        myprinter.Canvas.Draw( originx,originy,image1.picture.graphic);
        Myprinter.EndDoc;
        finally
        myprinter.free ;

      end;
    end;
  end;             

I have 2 printers, both lasers and both network accessible only.  For testing I have used the PDF24 printer driver and printed to a pdf file.  This works - either with draw or stretchdraw and produces the expected results. When attempting to print to one of the lasers however, I get no output. Looking at the printer queue I see a job in the printing state which after a few seconds changes to an error state. This cycles indefinitely.

After executing the print, I am able to use other features of the application normally, but when I exit the application (via application.terminate) I get an error.   In the case of running the application from the IDE, I get the first error message.  If I exit from running the executable directly, I get the second error message. The second message takes some time to appear.

Operating system is windows 11 and is current with all updates.
 
I have looked all over for examples of code to perform this print and have found a few different approaches and tried them all.  Some users have experienced a similar problem and I have seen posts which say that some printers simply cannot be printed to by Lazarus. Some produce no output and some produce erratic output. Some approaches I have tried produce the mysterious "Printer is Printing" error.

I have been working on this printing issue for several days - Does anyone have a better way to print the image - or an explanation for the errors?

bytebites:
myprinter.free is wrong, don't free it.

wp:
You assign the Printer (of unit printers) to a local variable myprinter, and at the end you destroy this myprinter. I think this is wrong because when you do "myprinter := Printer" you do not create a new instance of TPrinter, you simply copy the pointer. When you thus call "myprinter.Free" you really destroy the global Printer. And when the application terminates the Printers unit attempts to destroy Printer itself - which already had been destroyed by you, and this causes the error.

Another issue is that you access the Printer's properties before "PrintDialog.Execute". When a different printer is selected in the dialog, the PageWidth and PageHeight on which you had based the calculation of the destination image rectangle is no longer valid. Better to move this code after "PrintDialog.Execute".

The following modification of your code words correctly for me:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses  Math, Printers; function mm2px(mm: Double; DPI: Integer): Integer;begin  Result := round(mm/25.4 * DPI);end; procedure TForm1.Button1Click(Sender: TObject);const  OriginX_mm = 20;  // in millimeters  OriginY_mm = 20;  // in millimetersvar  R: TRect;  Scale: Double;  G: TGraphic;  OriginX, OriginY: Integer;begin  G := Image1.Picture.Graphic;   if PrintDialog1.Execute then  begin    OriginX := mm2px(OriginX_mm, Printer.XDPI);    OriginY := mm2px(OriginY_mm, Printer.YDPI);    Scale := Min((Printer.PageWidth - 2*OriginX)/G.Width, (Printer.PageHeight- 2*OriginY)/G.Height);    R := Rect(OriginX, OriginY, OriginX + round(G.Width * Scale), OriginY + round(G.Height * Scale));     Printer.BeginDoc;    try      Printer.Canvas.StretchDraw(R, G);      //Printer.Canvas.Draw(OriginX, OriginY, G);    finally      Printer.EndDoc;    end;  end;end;

woodguy:
Thanks Guys for the super fast replies. The error on exit problem is solved and even better thanks to WP I understand why.

Anyone have an idea how to get the lasers to print?  Their problem remains the same.  Is this one unsolveable?  I must have an old usb connected inkjet somewhere I can hook up and try but that really doesn't solve my problem. Is it the fact that they are network accessed or just those particular printers? One is HP and one Canon.

One again thanks for solving the error problem.

Ken

wp:
Sounds like a printer driver issue... Can you try to install a different printer driver? For a similar printer model, or a newer (or older) driver provided by the printer manufactorer, or a driver provided by Windows?

Navigation

[0] Message Index

[#] Next page

Go to full version