Mega Code Archive

 
Categories / Delphi / Forms
 

Jobs information (an easy way)

Title: Jobs information (an easy way)? Question: How to retrieve jobs information that is in the printer spooler? Answer: With Windows it is very easy to monitor the printed jobs. But sometimes and for a good reason the user need to monitor those jobs from inside the application. How? The answer is using the "EnumJobs" Windows API to retrieve the information (Job Name-Status-date-time...etc). To simplify the use of this Windows API I developed an easy function that receive the printer name and return an array of a structure, which represent the information needed. Here is the code for this function: uses WinSpool; .. type JOB_INFO_1_ARRAY = Array of JOB_INFO_1; .. Function GetSpoolerJobs(sPrinterName : String) : JOB_INFO_1_ARRAY; var i : Integer; hPrinter : THandle; bResult : Boolean; cbBuf : DWORD; pcbNeeded : DWORD; pcReturned : DWORD; aJobs : Array[0..99] of JOB_INFO_1; begin cbBuf := 1000; bResult := OpenPrinter(PChar(sPrinterName), hPrinter, Nil); if NOT bResult then begin ShowMessage('Error opening the printer'); exit; end; bResult := EnumJobs(hPrinter,0,Length(aJobs),1,@aJobs,cbBuf,pcbNeeded,pcReturned); if NOT bResult then begin ShowMessage('Error Getting Jobs information'); exit; end; ClosePrinter(hPrinter); for i:=0 to pcReturned-1 do begin if aJobs[i].pDocument Nil then begin SetLength(Result, Length(Result)+1); Result[Length(Result)-1] := aJobs[i]; end; end; end; An example of use: 1- Create a new project with a StringGrid and a Timer. 2- Set ColCount and RowCount properties of the string grid to 20. 3- Set the Interval property of the Timer to 500. 4- On the OnTime event of the timer write the following code : procedure TForm1.Timer1Timer(Sender: TObject); var i, ii : Integer; aJobs : JOB_INFO_1_ARRAY; begin for i:=0 to StringGrid1.ColCount-1 do for ii:=0 to StringGrid1.RowCount-1 do StringGrid1.Cells[i,ii] := ''; aJobs := GetSpoolerJobs('HP LaserJet 6L PCL'); for i:=0 to Length(aJobs)-1 do begin StringGrid1.Cells[i,0] := aJobs[i].pPrinterName; StringGrid1.Cells[i,1] := aJobs[i].pMachineName; StringGrid1.Cells[i,2] := aJobs[i].pUserName; StringGrid1.Cells[i,3] := aJobs[i].pDocument; StringGrid1.Cells[i,4] := aJobs[i].pDatatype; StringGrid1.Cells[i,5] := aJobs[i].pStatus; StringGrid1.Cells[i,6] := IntToStr(aJobs[i].Status); case aJobs[i].Status of JOB_STATUS_PAUSED: StringGrid1.Cells[i,6] := 'JOB_STATUS_PAUSED'; JOB_STATUS_ERROR: StringGrid1.Cells[i,6] := 'JOB_STATUS_ERROR'; JOB_STATUS_DELETING: StringGrid1.Cells[i,6] := 'JOB_STATUS_DELETING'; JOB_STATUS_SPOOLING: StringGrid1.Cells[i,6] := 'JOB_STATUS_SPOOLING'; JOB_STATUS_PRINTING: StringGrid1.Cells[i,6] := 'JOB_STATUS_PRINTING'; JOB_STATUS_OFFLINE: StringGrid1.Cells[i,6] := 'JOB_STATUS_OFFLINE'; JOB_STATUS_PAPEROUT: StringGrid1.Cells[i,6] := 'JOB_STATUS_PAPEROUT'; JOB_STATUS_PRINTED: StringGrid1.Cells[i,6] := 'JOB_STATUS_PRINTED'; JOB_STATUS_DELETED: StringGrid1.Cells[i,6] := 'JOB_STATUS_DELETED'; JOB_STATUS_BLOCKED_DEVQ: StringGrid1.Cells[i,6] := 'JOB_STATUS_BLOCKED_DEVQ'; JOB_STATUS_USER_INTERVENTION: StringGrid1.Cells[i,6] := 'JOB_STATUS_USER_INTERVENTION'; JOB_STATUS_RESTART: StringGrid1.Cells[i,6] := 'JOB_STATUS_RESTART'; JOB_POSITION_UNSPECIFIED: StringGrid1.Cells[i,6] := 'JOB_POSITION_UNSPECIFIED'; else StringGrid1.Cells[i,6] := 'Unknown status...'; end; end; StringGrid1.Refresh; end; 5- Run this project and try to print any documents using MSWord or any Windows Aplication and WATCH the stringgrid. Thats all. Any comments are welcome.