Как узнать, когда драйвер принтера Microsoft Print to PDF завершен? - PullRequest
2 голосов
/ 12 апреля 2019

Мне понадобился дешевый способ для приложения создать файл PDF. Поэтому я использую функции печати Windows API напрямую (CreateDC(), StartDoc(), StartPage(), EndPage(), EndDoc() и т. Д.) И выбираю Microsoft Print to PDF драйвер принтера.

Кроме того, я обнаружил, что если я установил для элемента lpszOutput структуры DOCINFO имя файла, драйвер запишет файл PDF в указанный файл без запроса имени пользователя.

Пока все хорошо. Но как мне узнать, когда файл PDF был создан? Существуют API-интерфейс диспетчера очереди печати, но драйвер не обязательно выполняется только потому, что выполняется диспетчер очереди печати. Или я мог бы создать цикл, который ищет файл, но, конечно, он будет существовать до того, как это будет сделано. Я также думал о попытке установить блокировку файла в моем цикле, который должен завершиться неудачей, если файл еще не существует или все еще записывается.

Но я не могу не задаться вопросом, есть ли более прямой способ узнать, когда файл PDF готов.

1 Ответ

0 голосов
/ 14 апреля 2019

Если вы используете GDI Print API (wingdi.h), то по этой ссылке показан пример кода, используемого для запроса статуса заданий на печать на принтере.

I 'м, включая код по ссылке, но вы также можете прочитать статью.

#include <Windows.h>
#include <wingdi.h>

BOOL GetJobs(HANDLE hPrinter,        /* Handle to the printer. */

             JOB_INFO_2 **ppJobInfo, /* Pointer to be filled.  */
             int *pcJobs,            /* Count of jobs filled.  */
             DWORD *pStatus)         /* Print Queue status.    */

{

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

  /* Get the buffer size needed. */
  if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded)) {
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
      return FALSE;
  }

  pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
  if (!(pPrinterInfo))
    /* Failure to allocate memory. */
    return FALSE;

  /* Get the printer information. */
  if (!GetPrinter(hPrinter,
                  2,
                  (LPSTR)pPrinterInfo,
                  cByteNeeded,
                  &cByteUsed)) {
    /* Failure to access the printer. */
    free(pPrinterInfo);
    pPrinterInfo = NULL;
    return FALSE;
  }

  /* Get job storage space. */
  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) {
    /* Failure to allocate Job storage space. */
    free(pPrinterInfo);
    pPrinterInfo = NULL;
    return FALSE;
  }

  ZeroMemory(pJobStorage, cByteNeeded);

  /* Get the list of jobs. */
  if (!EnumJobs(hPrinter,
                0,
                pPrinterInfo->cJobs,
                2,
                (LPBYTE)pJobStorage,
                cByteNeeded,
                (LPDWORD)&cByteUsed,
                (LPDWORD)&nReturned)) {
    free(pPrinterInfo);
    free(pJobStorage);
    pJobStorage = NULL;
    pPrinterInfo = NULL;
    return FALSE;
  }

  /*
  *  Return the information.
  */
  *pcJobs = nReturned;
  *pStatus = pPrinterInfo->Status;
  *ppJobInfo = pJobStorage;
  free(pPrinterInfo);

  return TRUE;

}

BOOL IsPrinterError(HANDLE hPrinter) {

  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;
      }
    }
  }

  /*
  *  No error condition.
  */
  free(pJobs);
  return FALSE;

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...