Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2010-11-25
16
Medium Priority
?
531 Views
Last Modified: 2012-05-10
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!
0
Comment
Question by:mccoymad
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 3
  • +1
16 Comments
 
LVL 14

Expert Comment

by:systan
ID: 34215128
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
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 34215133

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
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 34215135
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 24

Expert Comment

by:jimyX
ID: 34215527
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
 
LVL 24

Expert Comment

by:jimyX
ID: 34215539
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
 

Author Comment

by:mccoymad
ID: 34216910
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
 
LVL 24

Expert Comment

by:jimyX
ID: 34217211
>  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
 

Author Comment

by:mccoymad
ID: 34217224
You change PrimoPort port for LPT1 in Properties of print????
0
 
LVL 24

Expert Comment

by:jimyX
ID: 34217274
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
 

Author Comment

by:mccoymad
ID: 34217313
I know this!!!

I want to know if does not go to give error in the report when I print. !!!
0
 

Author Comment

by:mccoymad
ID: 34217318
I want to test the printer before printing.
0
 

Author Comment

by:mccoymad
ID: 34217375
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
 
LVL 24

Expert Comment

by:jimyX
ID: 34217678
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
 
LVL 32

Accepted Solution

by:
Ephraim Wangoya earned 2000 total points
ID: 34218536

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
 

Author Closing Comment

by:mccoymad
ID: 34219431
Very good
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question