Как отследить печать, отправленную на принтер через FastReport?

Я программирую на C++ Builder XE 10.4. Я написал программу, которая загружает страницу и отправляет её на печать. На реальном принтере, чтобы напечатать страницу, уходит примерно 7 секунд, на некоторых принтерах - 3-4 секунды, а на принтере для печати чеков - 2 секунды. Вопрос: как мне узнать о завершении печати?


Ответы (2 шт):

Автор решения: Sheridan

Почитайте эту статью. Если кратко - надо опросить spool и посмотреть в поле Status структуры JOB_INFO_2:

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;

}
→ Ссылка
Автор решения: Robik

В интернете искал и нашел один ответ, он работает. Там можно такой алгоритм сделать, на примере принтера “А” нижеперечисленному коду можно узнать общее количество задании у принтера “А”. Если у принтера нет задании, то функция вернет 0, если есть, то количество задании. Но там только один изъян есть, если произошла ошибка в процессе печати, то это задание останется в очереди, и это логично. В будущем хорошо было бы ответить на вопрос (“Если в очереди принтера А 10 заданий, то из них какое количество ошибки печати?”).

int get_jobs_print(const AnsiString& PrinterName)

    {
    int job_count = -1;
    
        PRINTER_INFO_2 *Pr;
        DWORD byteNeed = 0,prCount=0;
        EnumPrinters(PRINTER_ENUM_CONNECTIONS|PRINTER_ENUM_LOCAL,NULL,2,NULL,0,&byteNeed,&prCount);
        Pr = new PRINTER_INFO_2 [byteNeed];
        if(EnumPrinters(PRINTER_ENUM_CONNECTIONS|PRINTER_ENUM_LOCAL,NULL,2,(LPBYTE)Pr,byteNeed,&byteNeed,&prCount))
        {
            for(int i = 0; i < prCount; ++i)
            {
            if (AnsiString(Pr[i].pPrinterName)== PrinterName)
            {
             job_count = Pr[i].cJobs;
            }
        }
        delete Pr;
        }
    
        return job_count;
    
    };
→ Ссылка