15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Как узнать состояние принтера, а так же заданий на принтере.

Следующий пример демонстрирует, как использовать функцию EnumJobs для получения структуры JOB_INFO и как использовать функцию GetPrinter для получения структуры PRINTER_INFO:

Пример

   BOOL GetJobs(HANDLE hPrinter,      /* Дескриптор принтера. */
        JOB_INFO_2 **ppJobInfo, /* Указатель который будем заполнять.*/ 
        int *pcJobs,            /* Счётчик заданий. */ 
        DWORD *pStatus)         /* Состояние очереди печати.*/ 

   {

   DWORD               cByteNeeded,
                        nReturned,
                        cByteUsed;
    JOB_INFO_2          *pJobStorage = NULL;
    PRINTER_INFO_2       *pPrinterInfo = NULL;

   /* Получаем необходимый размер буфера. */ 
       if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
       {
           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
               return FALSE;
       }

       pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
       if (!(pPrinterInfo))
           /* Ошибка выделения памяти. */ 
           return FALSE;

       /* Получаем информацию о принтере. */ 
       if (!GetPrinter(hPrinter,
               2,
               (LPSTR)pPrinterInfo,
               cByteNeeded,
               &cByteUsed))
       {
           /* Ошибка доступа к принтеру. */ 
           free(pPrinterInfo);
           pPrinterInfo = NULL;
           return FALSE;
       }

       /* Получаем необходимы размер для заданий. */ 
       if (!EnumJobs(hPrinter,
               0,
               pPrinterInfo->cJobs,
               2,
               NULL,
               0,
               (LPDWORD)&cByteNeeded,
               (LPDWORD)&nReturned))
       {
           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
           {
               free(pPrinterInfo);
               pPrinterInfo = NULL;
               return FALSE;
           }
       }

       pJobStorage = (JOB_INFO_2 *)malloc(cByteNeeded);
       if (!pJobStorage)
       {
           /* Ошибка выделения памяти для информации о заданиях. */ 
           free(pPrinterInfo);
           pPrinterInfo = NULL;
           return FALSE;
       }

       ZeroMemory(pJobStorage, cByteNeeded);

       /* Получаем список заданий. */ 
       if (!EnumJobs(hPrinter,
               0,
               pPrinterInfo->cJobs,
               2,
               (LPBYTE)pJobStorage,
               cByteNeeded,
               (LPDWORD)&cByteUsed,
               (LPDWORD)&nReturned))
       {
           free(pPrinterInfo);
           free(pJobStorage);
           pJobStorage = NULL;
           pPrinterInfo = NULL;
           return FALSE;
       }

       /*
        *  Возвращаем информацию.
        */ 
       *pcJobs = nReturned;
       *pStatus = pPrinterInfo->Status;
       *ppJobInfo = pJobStorage;
       free(pPrinterInfo);

       return TRUE;

   }

   BOOL IsPrinterError(HANDLE hPrinter)
   {

       JOB_INFO_2  *pJobs;
       int         cJobs,
                   i;
       DWORD       dwPrinterStatus;

       /*
        *  Получаем информацию о состоянии очереди принтера и
        *  заданиях в очереди принтера.
        */ 
       if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus))
           return FALSE;

       /*
        *  Если на принтере ошибка, то возвращаем ошибку.
        */ 
       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))
       {
           return TRUE;
       }

       /*
        *  Находим задание в очереди, которое печатается.
        */ 
       for (i=0; i < cJobs; i++)
       {
           if (pJobs[i].Status & JOB_STATUS_PRINTING)
           {
               /*
                *  Если задание в состоянии ошибки,
                *  то возвращаем ошибку.
                */ 
               if (pJobs[i].Status &
                   (JOB_STATUS_ERROR |
                   JOB_STATUS_OFFLINE |
                   JOB_STATUS_PAPEROUT |
                   JOB_STATUS_BLOCKED_DEVQ))
               {
                   return TRUE;
               }
           }
       }

       /*
        *  Ошибок на принтере нет.
        */ 
       return FALSE;

   }