Брацы! OpenPrinter не отслеживает что принтер отключен! Что делать?

13:43
Thomas:

The amount of status information available via the Windows API depends on
what print monitors are installed. In any case, status info is generally
only available when one or more jobs are queued. The PrinterStatus()
function in the following unit will return you a descriptive status string
(and the status flags and job count are also returned) for display:

unit PrintStatus;
 
interface
function PrinterStatus(var aStatus: LongWord; var aNrJobs: Integer): string;
 
implementation
uses Windows, SysUtils, Printers, WinSpool;
 
resourcestring
rsNrJobsWaiting = '%0:u document(s) waiting';
rsStatusSep = '; ';
 
rsStatusIdle = 'Idle';
rsStatusUnknown = 'Unknown';
rsStatusBusy = 'Busy';
rsStatusDoorOpen = 'Door open';
rsStatusError = 'Error';
rsStatusInitializing = 'Initialising';
rsStatusIOActive = 'I/O active';
rsStatusManualFeed = 'Manual feed';
rsStatusNoToner = 'No toner';
rsStatusNotAvailable = 'Not available';
rsStatusOffline = 'Offline';
rsStatusOutOfMemory = 'Out of memory';
rsStatusOutputBinFull = 'Output bin full';
rsStatusPagePunt = 'Page punt';
rsStatusPaperJam = 'Paper jam';
rsStatusPaperOut = 'Paper out';
rsStatusPaperProblem = 'Paper problem';
rsStatusPaused = 'Paused';
rsStatusPendingDeletion = 'Pending deletion';
rsStatusPowerSave = 'Power-save';
rsStatusPrinting = 'Printing';
rsStatusProcessing = 'Processing';
rsStatusServerUnknown = 'Server unknown';
rsStatusTonerLow = 'Toner low';
rsStatusUserIntervention = 'User intervention';
rsStatusWaiting = 'Waiting';
rsStatusWarmingUp = 'Warming up';
 
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.


--------------------
Regards,
Steve Moss, CoCo Systems Ltd.