How I make to test if the printer will go to print a report without giving error?

Attention, my doubt is not if the printer is on line or off line, what I want to know I am if does not go to give error in the report when will be to print.

An example of error when printing is when the using one changes drive of the installed printer, then when it is ordered to print the error occurs. I want to detect this type of error before printing the report!
mccoymadAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
Ephraim WangoyaConnect With a Mentor Commented:

Try this code, you may have to cancel the job if the printer is no good
uses
  WinSpool, Printers, Registry;

//you can use your own methods to get the printer port
function GetPrinterPort(const APrinterName: String): string;
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  with Reg do
  begin
    RootKey := HKEY_LOCAL_MACHINE;
     if OpenKey('\System\CurrentControlSet\Control\Print\printers\' + APrintername + '\', True) then
       if ValueExists('port') then
         Result := Readstring('port');
      CloseKey;
  end;
end;

//this is what determines if you can print
function GetJobStatus(APrinterHandle, AJobNumber: THandle): Boolean;
type
  TJobs = array [0..1000] of JOB_INFO_1;
  PJobs = ^TJobs;
var
  BytesNeeded, NumOfJobs, I: Cardinal;
  PJ: PJobs;
begin
  Result := True;
  EnumJobs(APrinterHandle, 0, 1000, 1, nil, 0, BytesNeeded, NumOfJobs);
  pJ := AllocMem(BytesNeeded);
  Result := EnumJobs(APrinterHandle, 0, 1000, 1, pJ, BytesNeeded, BytesNeeded, NumOfJobs);
  if Result and (NumOfJobs > 0) then
    for I := 0 to Pred(NumOfJobs) do
    begin
      if pJ^[i].JobId = AJobNumber then
      begin
        Result := (pJ^[i].Status AND $2) <> $2;
        if not Result then
          Exit;
      end;
    end;
end;

function IsValidPrinter(const APrinterName: string): Boolean;
var
  hPrn : THandle;
  DocInfo1 : TDocInfo1;
  PPort: string;
  PrintJob: THandle;
  PPrinter: PChar;
begin
  PPrinter := PChar(APrinterName);
  Result := OpenPrinter(PPrinter, hPrn,  nil);
  if Result then
  begin
    PPort := Trim(GetPrinterPort(APrinterName));
    if PPort = '' then
    begin
      Result := False;
      Exit;
    end;
    if PPort[Length(PPort)] = ':' then
      SetLength(PPort, Length(PPort) -1);

    DocInfo1.pDocName := 'Test';
    DocInfo1.pOutputFile := PChar(PPort);
    DocInfo1.pDataType := 'RAW';
    PrintJob := StartDocPrinter(hPrn, 1, @DocInfo1);
    Result := PrintJob <> 0;
    if Result then
    begin
      EndDocPrinter(hPrn); //if the printer is no good it will error out
      Sleep(1000); //delay a little longer to get status
      Result := GetJobStatus(hPrn, PrintJob);
      //if not result, you may need to cancel the printjob 
    end;
    ClosePrinter(hPrn)
  end;
end;

Open in new window

0
 
systanCommented:
hi
try to drop TPrintDialog
if NOT printDialog1.execute then 
begin
     showmessage('NO printer selected');
end
else
begin
     showmessage('Starting to print');
end;

Open in new window

0
 
Ephraim WangoyaCommented:

uses
  WinSpool

function IsValidPrinter(const APrinterName: string): Boolean;
var
  prnHandle: THandle;
begin
  Result := OpenPrinter(PChar('APrinterName'), prnHandleHandle, nil);
  if Result then
    CloseHandle(prnHandle);
end;

0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Ephraim WangoyaCommented:
typo

uses
  WinSpool

function IsValidPrinter(const APrinterName: string): Boolean;
var
  prnHandle: THandle;
begin
  Result := OpenPrinter(PChar('APrinterName'), prnHandle, nil);
  if Result then
    CloseHandle(prnHandle);
end;

0
 
jimyXCommented:
To be able to detect any error if the driver is corrupted or is missing files all you have to do is call GetMapMode and catch the error in Try-Except block.

The following code will validate the default printer.

uses Printers;

function IsDeviceValid():integer;
begin
  result := 0;
  if Printer.PrinterIndex < 0 then
    begin
      result := 0;
      Exit;
    end;
  try
    GetMapMode(Printer.Handle);
    result := 1;
  except
    Printer.PrinterIndex := -1;
    result := -1;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if IsDeviceValid() = 1 then
    showmessage('Valid printer')
  else
    if IsDeviceValid() = 0 then
      showmessage('No printer available !')
    else
      showmessage('Printer error');
end;

Open in new window

0
 
jimyXCommented:
This will validate a printer by passing its name:

uses Printers, Winspool;

function PrinterHandleByName(PrinterName:string):THandle;
begin
   Result:=0;
   if not OpenPrinter(PChar(PrinterName), result, nil) then
     RaiseLastOSError
   else
   begin
     ClosePrinter(result) ;
   end
end;

function IsDeviceValid(PrinterName:String):integer;
begin
  result := 0;
  if Printer.PrinterIndex < 0 then
    begin
      result := 0;
      Exit;
    end;
  try
    GetMapMode(PrinterHandleByName(PrinterName));
    result := 1;
  except
    Printer.PrinterIndex := -1;
    result := -1;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if IsDeviceValid('YourPrinterName') = 1 then
    showmessage('Valid printer')
  else
    if IsDeviceValid() = 0 then
      showmessage('No printer available !')
    else
      showmessage('Printer error');
end;

Open in new window

0
 
mccoymadAuthor Commented:
No suggestion functioned!!

An example of error when printing: installs a virtual printer call PrimoPdf, www.primopdf.com , later it goes in Properties/Port and it modifies the PrimoPort port for LPT1. Now all time that will be to print a document in this printer will go to occur error in the impression!

Necessary to detect this type of error before printing the document

My Code

  function IsValidPrinter(const APrinterName: string): Boolean;
  var
    prnHandle: THandle;
  begin
    Result := OpenPrinter(PChar(APrinterName), prnHandle, nil);
    if Result then begin
      try
        getmapmode(prnHandle);
      except
        Result := False;
      end;
      ClosePrinter(prnHandle);
    end;  
  end;
0
 
jimyXCommented:
>  No suggestion functioned!!
That is not a printer error.

I installed the PrimoPdf and did test it, and my findings was that, it is a problem of handling the print job and not a problem of sending the print job.

PrimoPdf requires manual processing of printer jobs. Whenever you print using the PrimoPdf it will not be processed until you press "Create PDF" then it will be processed.

Try that please.

PrimoPdf.JPG
0
 
mccoymadAuthor Commented:
You change PrimoPort port for LPT1 in Properties of print????
0
 
mccoymadAuthor Commented:
0
 
jimyXCommented:
But PrimoPdf is different than the LPT1 actually the PrimoPdf is a converter so whenever you print something to it, that will be converted to PDF document but the process goes in printing operation.

What you are trying to do is not supported by PrimoPdf and can not be done. What you are trying to do is exactly like setting HP physical printer at the LPT1 port and change the port to Com1 which is not going to work because the connection and the configuration has been done to LPT1 (Printer Port) while the job will be sent to somewhere else.

You are trying to make PrimoPdf as an interface to the LPT1 printer (if there is any) that's what is giving you fail message when sending from PrimoPdf to LPT1 and not the printing itself.
0
 
mccoymadAuthor Commented:
I know this!!!

I want to know if does not go to give error in the report when I print. !!!
0
 
mccoymadAuthor Commented:
I want to test the printer before printing.
0
 
mccoymadAuthor Commented:
The alteration of the door of the PrimoPDF printer is an EXAMPLE that provokes error in the impression!

I do not want to make this, I said only one situation example that provokes the error in the impression!

Before printing the document, I need a routine that check if goes to occur error or not in the impression!

You understood?
0
 
jimyXCommented:
I see. But your are doing a complicated approach which is checking the printer itself for printer error meanwhile you can check for print error, which occurs when performing printing command.

That error can be discovered when the print job is sent to the printer and the printer fails to handle it in Try-Except block.

For example that's possible when trying to print a QuickReport, after preparing some field in it, and catch the error that arise when printing, as follows:

try
    Form1.QuickRep.Print;
  except
    MessageDlg('Error printing.',mtError,[mbok],0);
  end;

Open in new window

0
 
mccoymadAuthor Commented:
Very good
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.