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

Брацы! 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.