JOB_INFO_2 *pJobs;
int cJobs,
i;
DWORD dwPrinterStatus;
/*
* Get the state information for the Printer Queue and
* the jobs in the Printer Queue.
*/
if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus))
return FALSE;
/*
* If the Printer reports an error, believe it.
*/
if (dwPrinterStatus &
(PRINTER_STATUS_ERROR |
PRINTER_STATUS_PAPER_JAM |
PRINTER_STATUS_PAPER_OUT |
PRINTER_STATUS_PAPER_PROBLEM |
PRINTER_STATUS_OUTPUT_BIN_FULL |
PRINTER_STATUS_NOT_AVAILABLE |
PRINTER_STATUS_NO_TONER |
PRINTER_STATUS_OUT_OF_MEMORY |
PRINTER_STATUS_OFFLINE |
PRINTER_STATUS_DOOR_OPEN))
{
free( pJobs );
return TRUE;
}
/*
* Find the Job in the Queue that is printing.
*/
for (i=0; i < cJobs; i++)
{
if (pJobs[i].Status & JOB_STATUS_PRINTING)
{
/*
* If the job is in an error state,
* report an error for the printer.
* Code could be inserted here to
* attempt an interpretation of the
* pStatus member as well.
*/
if (pJobs[i].Status &
(JOB_STATUS_ERROR |
JOB_STATUS_OFFLINE |
JOB_STATUS_PAPEROUT |
JOB_STATUS_BLOCKED_DEVQ))
{
free( pJobs );
return TRUE;
}
}
}
MPrtInfo. This component let you access to Windows95/98 and NT structures containing virtually any information provided by the system about installed printers and their pending jobs. Structures available are: PRINTER_INFO_1, 2, 3, 4 and 5, DEVMODE, JOB_INFO_1 and 2 (see Win32 online help for details), plus some obvious properties (installed printer names list, selected printer name and index in the list and so on). Methods to pause, resume and clear printers and jobs, some printer configuration dialogs. Events to monitor printer and printer jobs status changes.
function PrinterStatus(var aStatus: LongWord; var aNrJobs: Integer): string;
var
Idx: Integer;
procedure AddStatus(aStr: string);
begin
if Result <> '' then Result := Result + rsStatusSep;
Result := Result + aStr
end;
function NewStatus(var aNJ: Integer): LongWord;
var
Count: LongWord;
DevName: string;
hPrinter: THandle;
JobInfoCount: LongWord;
JobInfo2: PJobInfo2;
PrinterInfo2: PPrinterInfo2;
begin
Result := 0;
DevName := Printer.Printers[Printer.PrinterIndex];
if OpenPrinter(PChar(DevName),hPrinter,nil) then
begin
Count := 0;
GetPrinter(hPrinter,2,nil,0,@Count);
if Count > 0 then
begin
GetMem(PrinterInfo2,Count);
GetPrinter(hPrinter,2,PrinterInfo2,Count,@Count);
Result := PrinterInfo2.Status;
aNJ := PrinterInfo2.cJobs;
FreeMem(PrinterInfo2);
if aNJ > 0 then
begin
Count := 0;
EnumJobs(hPrinter,0,1,2,nil,0,Count,JobInfoCount);
if Count > 0 then
begin
GetMem(JobInfo2,Count);
EnumJobs(hPrinter,0,1,2,JobInfo2,Count,Count,JobInfoCount);
if (JobInfoCount > 0) and (JobInfo2.Status <> 0) then
begin
if (JobInfo2.Status and JOB_STATUS_BLOCKED_DEVQ) <> 0 then
Result := Result or PRINTER_STATUS_ERROR;
if (JobInfo2.Status and JOB_STATUS_DELETING) <> 0 then
Result := Result or PRINTER_STATUS_PENDING_DELETION;
if (JobInfo2.Status and JOB_STATUS_ERROR) <> 0 then
Result := Result or PRINTER_STATUS_ERROR;
if (JobInfo2.Status and JOB_STATUS_OFFLINE) <> 0 then
Result := Result or PRINTER_STATUS_OFFLINE;
if (JobInfo2.Status and JOB_STATUS_PAPEROUT) <> 0 then
Result := Result or PRINTER_STATUS_PAPER_OUT;
if (JobInfo2.Status and JOB_STATUS_PAUSED) <> 0 then
Result := Result or PRINTER_STATUS_PAUSED;
if (JobInfo2.Status and
(JOB_STATUS_PRINTING or JOB_STATUS_RESTART)) <> 0 then
Result := Result or PRINTER_STATUS_PRINTING;
if (JobInfo2.Status and JOB_STATUS_USER_INTERVENTION) <> 0
then
Result := Result or PRINTER_STATUS_USER_INTERVENTION;
end;
FreeMem(JobInfo2)
end
end
end;
ClosePrinter(hPrinter)
end
end;
begin
Result := '';
aNrJobs := 0;
aStatus := NewStatus(aNrJobs);
if aStatus = 0 then
begin
if aNrJobs > 0 then
Result := rsStatusPrinting
else
Result := rsStatusIdle
end
else
begin
if (aStatus and PRINTER_STATUS_BUSY <> 0) then AddStatus(rsStatusBusy);
if (aStatus and PRINTER_STATUS_DOOR_OPEN <> 0) then
AddStatus(rsStatusDoorOpen);
if (aStatus and PRINTER_STATUS_ERROR <> 0) then
AddStatus(rsStatusError);
if (aStatus and PRINTER_STATUS_INITIALIZING <> 0) then
AddStatus(rsStatusInitializing);
if (aStatus and PRINTER_STATUS_IO_ACTIVE <> 0) then
AddStatus(rsStatusIOActive);
if (aStatus and PRINTER_STATUS_MANUAL_FEED <> 0) then
AddStatus(rsStatusManualFeed);
if (aStatus and PRINTER_STATUS_NO_TONER <> 0) then
AddStatus(rsStatusNoToner);
if (aStatus and PRINTER_STATUS_NOT_AVAILABLE <> 0) then
AddStatus(rsStatusNotAvailable);
if (aStatus and PRINTER_STATUS_OFFLINE <> 0) then
AddStatus(rsStatusOffline);
if (aStatus and PRINTER_STATUS_OUT_OF_MEMORY <> 0) then
AddStatus(rsStatusOutOfMemory);
if (aStatus and PRINTER_STATUS_OUTPUT_BIN_FULL <> 0) then
AddStatus(rsStatusOutputBinFull);
if (aStatus and PRINTER_STATUS_PAGE_PUNT <> 0) then
AddStatus(rsStatusPagePunt);
if (aStatus and PRINTER_STATUS_PAPER_JAM <> 0) then
AddStatus(rsStatusPaperJam);
if (aStatus and PRINTER_STATUS_PAPER_OUT <> 0) then
AddStatus(rsStatusPaperOut);
if (aStatus and PRINTER_STATUS_PAPER_PROBLEM <> 0) then
AddStatus(rsStatusPaperProblem);
if (aStatus and PRINTER_STATUS_PAUSED <> 0) then
AddStatus(rsStatusPaused);
if (aStatus and PRINTER_STATUS_PENDING_DELETION <> 0) then
AddStatus(rsStatusPendingDeletion);
if (aStatus and PRINTER_STATUS_POWER_SAVE <> 0) then
AddStatus(rsStatusPowerSave);
if (aStatus and PRINTER_STATUS_PRINTING <> 0) then
AddStatus(rsStatusPrinting);
if (aStatus and PRINTER_STATUS_PROCESSING <> 0) then
AddStatus(rsStatusProcessing);
if (aStatus and PRINTER_STATUS_SERVER_UNKNOWN <> 0) then
AddStatus(rsStatusServerUnknown);
if (aStatus and PRINTER_STATUS_TONER_LOW <> 0) then
AddStatus(rsStatusTonerLow);
if (aStatus and PRINTER_STATUS_USER_INTERVENTION <> 0) then
AddStatus(rsStatusUserIntervention);
if (aStatus and PRINTER_STATUS_WAITING <> 0) then
AddStatus(rsStatusWaiting);
if (aStatus and PRINTER_STATUS_WARMING_UP <> 0) then
AddStatus(rsStatusWarmingUp)
end;
if aNrJobs > 0 then
Result := Result + rsStatusSep + Format(rsNrJobsWaiting,[aNrJobs])
end;
end.
function TestPrinterStatus(LPTPort: Word): Byte;
var
Status: byte;
CheckLPT: word;
begin
Status := 0;
if (LPTPort >= 1) and (LPTPort <= 3) then
begin
CheckLPT := LPTPort - 1;
asm
mov dx, CheckLPT;
mov al, 0;
mov ah, 2;
int 17h;
mov &Status, ah;
end;
end;
Result := Status;
end;
{
Pass in the LPT port number you want to check & get the following back:
01h - Timeout
08h - I/O Error
10h - Printer selected
20h - Out of paper
40h - Printer acknowledgement
80h - Printer not busy (0 if busy)
Note:
This function doesn't work under NT, it gives an access violation
from the DOS interrupt call.
}