Link to home
Start Free TrialLog in
Avatar of Jaymol
Jaymol

asked on

Capture print details.

Hi.

Is it possible to capture information about print requests as they go to a printer?  I'm considering writing a service or systray application that keeps a log of print jobs as one of my applications is becoming a little unstable after running solidly for about 4 months.

I just want to get the info that you get when you open the printer icon from the system tray.

Thanks,

John.
Avatar of DrDelphi
DrDelphi

Take a look at the EnumJobs API function. This doesn't give you an "event" to catch a print job starting, but it will give you the information about jobs pending/printing.


God luck!!
// The Windows print spooler regularly broadcasts a system wide
// WM_SPOOLERSTATUS message each time a job is added or deleted from the
// spooler que. The following example demonstrates trapping for this
// message.

type
  TForm1 = class(TForm)
    Label1: TLabel;
  private
    { Private declarations }
    procedure WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS); message WM_SPOOLERSTATUS;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS);
begin
  Lable1.Caption := IntToStr(msg.JobsLeft)+' Jobs currenly in spooler';
  msg.Result := 0;
end;
Sorry I think that you need name and not numbers . Try this:

uses Printers, WinSpool;

function PrinterStatusText(Status: Integer): String;
begin
  case Status of
    0:                            Result := 'Waiting';
    JOB_STATUS_PAUSED:            Result := 'Paused';
    JOB_STATUS_ERROR:             Result := 'Error';
    JOB_STATUS_DELETING:          Result := 'Deleting';
    JOB_STATUS_SPOOLING:          Result := 'Spooling';
    JOB_STATUS_PRINTING:          Result := 'Printing';
    JOB_STATUS_OFFLINE:           Result := 'Offline';
    JOB_STATUS_PAPEROUT:          Result := 'Paper Out';
    JOB_STATUS_PRINTED:           Result := 'Printed';
    JOB_STATUS_DELETED:           Result := 'Deleted';
    JOB_STATUS_BLOCKED_DEVQ:      Result := 'Blocked';
    JOB_STATUS_USER_INTERVENTION: Result := 'User Intervention';
    JOB_STATUS_RESTART:           Result := 'Restart';
  else Result := 'Status ' + IntToStr(Status);
  end;
end;

procedure GetJobs(PrinterName: String; JobList: TStrings);
const
  InfoLevel = 1;
  FirstJob = 0;
  LastJob = 19;
var
  Jobs: array [FirstJob..LastJob] of TJobInfo1;
  PrinterHandle, BytesNeeded, I, NumJobs: Integer;
begin
  if OpenPrinter(PChar(PrinterName),PrinterHandle,nil) then begin
    if
EnumJobs(PrinterHandle,FirstJob,LastJob+1,InfoLevel,@Jobs,SizeOf(Jobs),BytesNeed
ed,NumJobs) then begin
      JobList.Clear;
      for I := 0 to NumJobs-1 do
      with Jobs[I] do
        JobList.Add(Format('%s
(%s)',[StrPas(pDocument),PrinterStatusText(Status)]));
    end;
    ClosePrinter(PrinterHandle);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetJobs('HP Laserjet 4P',Memo1.Lines);
end;


ASKER CERTIFIED SOLUTION
Avatar of ginsonic
ginsonic
Flag of Romania image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Mohammed Nasman
Take a look at, some links for the printing

http://homepages.borland.com/efg2lab/Library/Delphi/Printing/
Avatar of Jaymol

ASKER

What can I say?  Thanks for the code.

John.
Avatar of Jaymol

ASKER

One thing though - your code very nicely tells me everything that's going on at the click of a button, but it doesn't capture the print event.  I need this info to be captured automatically.  Can you please give me code to complete the question fully.

Thanks,

John.
I will try .
Untill then you can replace the click event with a timer.
Avatar of Jaymol

ASKER

Adding a timer's a bit lame.

I need to capture every single print job - not just the ones that last longer than my timer interval.

John.