2013-12-10 6 views
1

Что мне нужно - снова переустановить буферный файл (не задание *), установив новое количество копий.AddJob + SetPrinter: возможно ли установить dmCopies и получить эффект?

До сих пор следующие попытки были опробованы:

  • OpenPrinter, AddJob, SetJob (с JOB_INFO_2-> pDevMode)
  • OpenPrinter, SetPrinter, DocumentProperties, AddJob, SetJob
  • OpenPrinter, StartDocPrinter, StartPagePrinter, WritePrinter

Многочисленные комбинации ClosePrinter и ряд обходных решений для SetPrinter..DocumentProperties часть - без успеха.

Изменение принтеров (от HP до Brother), перезапуск спулера и ПК - бездействия.

В списке заданий на печать показано, что установлено несколько копий. Однако то, что я получаю от принтера, является одной копией.

Кроме того, pDevMode->dmFields имеет |= DM_COPIES во всех соответствующих случаях.

Итак, есть ли эффективный маршрут для установки количества копий, возможно, других параметров (сопоставление) и печати необработанного документа PCL/PS без перехода в GDI или многократной печати задания?

#include "006_pclblacky_t.h" 
#define PNAME L"HP" 

t_006pclblacky::t_006pclblacky() 
{ 
     settings.color.set = false; 
     settings.copies.set = false; 
     settings.ori.set = false; 
     settings.paper.set = false; 
} 


t_006pclblacky::~t_006pclblacky() 
{ 
} 

int t_006pclblacky::Run() 
{ 
     int rc = 0; 

     rc = subtest_001(); 
     if (rc != 0) return rc; 

     return 0; 

} 

void t_006pclblacky::defaults() { 
} 

void t_006pclblacky::GetJobInfo(int JobId) 
{ 
     HANDLE ph; 
     DOC_INFO_1 di1; 
     DWORD dwRead, dwWritten; 
     DWORD x,y,z; 
     int rc; 
     PRINTER_DEFAULTSW Defaults = { NULL, NULL, PRINTER_ALL_ACCESS}; 
     OpenPrinter(PNAME, &ph, &Defaults); 


     try { 
       rc = GetJob(ph, JobId, 1, NULL, 0, &x); 
       if (rc != 122 && x < 1) { 
         assert(122 == 0); 
       } 
     } catch (...) { 
       assert(1 == 0); 
     } 

     JOB_INFO_1 *jg1 = (JOB_INFO_1*)malloc(x); 
     try { 
       GetJob(ph, JobId, 1, (LPBYTE)jg1, x, &y); 
     } catch (...) { 
       assert(1 == 0); 
     } 

     jg1->TotalPages = 2; 


     rc = SetJob(ph, JobId, 1, (LPBYTE)jg1, JOB_CONTROL_PAUSE); 
     assert (rc > 0); 
     rc = GetLastError(); 

     try { 
       if (GetJob(ph, JobId, 2, NULL, 0, &x) != 122 && x < 1) { 
         assert(122 == 0); 
       } 
     } catch (...) { 
       assert(1 == 0); 
     } 
     //jg1->PagesPrinted = 1; 

     JOB_INFO_2 *jg2 = (JOB_INFO_2*)malloc(x); 
     try { 
       GetJob(ph, JobId, 2, (LPBYTE)jg2, x, &y); 
     } catch (...) { 
       assert(1 == 0); 
     } 
} 


void t_006pclblacky::SendFileToPrinter(LPCWSTR fileName, LPWSTR docName) 
{ 

     HANDLE ph; 
     DOC_INFO_1 di1; 
     DWORD dwRead, dwWritten; 


     std::ifstream file(fileName, ios::in | ios::binary | ios::ate); 
     std::ifstream::pos_type fileSize; 
     char* fileContents; 
     int rc; 
     PRINTER_DEFAULTSW Defaults = { NULL, NULL, PRINTER_ALL_ACCESS}; 
     LPDEVMODE devmOld = NULL; 
     OpenPrinter(PNAME, &ph, &Defaults); 

     di1.pDatatype = L"RAW"; // IsV4Driver("Printer Name") ? "XPS_PASS" : "RAW"; 
     di1.pDocName = docName; 
     di1.pOutputFile = NULL; 

     fileSize = file.tellg(); 
     if (fileSize < 1) { 
       return; 
     } 

     fileContents = new char[fileSize]; 
     file.seekg(0, ios::beg); 
     if (!file.read(fileContents, fileSize)) 
     { 
     assert(0 == 1); 
     } 

     dwRead = fileSize; 

     if (!settings.ori.set && !settings.color.set && !settings.copies.set && !settings.paper.set) { 
       StartDocPrinter(ph, 1, (LPBYTE)&di1); 

       StartPagePrinter(ph); 

       if (file.is_open()) 
       { 
         WritePrinter(ph, fileContents, dwRead, &dwWritten); 
         file.close(); 
       } 
       else { 
         assert(0 == 1); 
       } 

       EndPagePrinter(ph); 

       EndDocPrinter(ph); 
     } else { 
       devmOld = GetPrinterParams(ph); 
       ClosePrinter(ph); 
       Defaults.pDevMode = devmOld; 
       OpenPrinter(PNAME, &ph, &Defaults); 
       //ClosePrinter(ph); 
       //OpenPrinter(PNAME, &ph, &Defaults); 
       SetPrinterParams(ph); 
       //ClosePrinter(ph); 
       //OpenPrinter(PNAME, &ph, &Defaults); 

       int tsz = sizeof(ADDJOB_INFO_1)+MAX_PATH+1; 
       ADDJOB_INFO_1 *aji = (ADDJOB_INFO_1*)malloc(tsz); 
       DWORD d = 0; 
       rc = AddJob(ph, 1, (LPBYTE)aji, tsz, &d); 
       if (rc == 0) { 
         rc = GetLastError(); 
       } 
       assert (aji->JobId != 0); 

       DWORD x,y,z; 

       try { 
         rc = GetJob(ph, aji->JobId, 1, NULL, 0, &x); 
         if (rc != 122 && x < 1) { 
           assert(122 == 0); 
         } 
       } catch (...) { 
         assert(1 == 0); 
       } 

       JOB_INFO_1 *jg1 = (JOB_INFO_1*)malloc(x); 
       try { 
         GetJob(ph, aji->JobId, 1, (LPBYTE)jg1, x, &y); 
       } catch (...) { 
         assert(1 == 0); 
       } 

       /*JOB_INFO_1 *ji1 = (JOB_INFO_1*)malloc(sizeof(JOB_INFO_1)); 
       ji1->pDatatype = L"RAW"; 
       ji1->pPrinterName = jg1->pPrinterName; 
       ji1->TotalPages = 2; // test 
       ji1->pDocument = jg1->pDocument; 
       ji1->pMachineName = jg1->pMachineName; 
       ji1->pUserName = jg1->pUserName;*/ 
       jg1->TotalPages = 1; 
       jg1->pDocument = docName; 


       rc = SetJob(ph, aji->JobId, 1, (LPBYTE)jg1, JOB_CONTROL_PAUSE); 
       assert (rc > 0); 
       rc = GetLastError(); 

       try { 
         if (GetJob(ph, aji->JobId, 2, NULL, 0, &x) != 122 && x < 1) { 
           assert(122 == 0); 
         } 
       } catch (...) { 
         assert(1 == 0); 
       } 
       jg1->PagesPrinted = 2; 
       jg1->TotalPages = 2; 

       JOB_INFO_2 *jg2 = (JOB_INFO_2*)malloc(x); 
       try { 
         GetJob(ph, aji->JobId, 2, (LPBYTE)jg2, x, &y); 
       } catch (...) { 
         assert(1 == 0); 
       } 
       /*JOB_INFO_2 *ji2 = (JOB_INFO_2*)malloc(sizeof(JOB_INFO_2)); 
       ji2->pDevMode = (PDEVMODE)malloc(sizeof(DEVMODE)); 
       ji2->pDevMode->dmPaperSize = settings.paper.val; 
       ji2->pDatatype = L"RAW"; 
       ji2->pPrinterName = jg2->pPrinterName; 
       ji2->TotalPages = 2; 
       */ 

       DWORD dmf = jg2->pDevMode->dmFields; 
       dmf = DM_COLLATE; 


       if (settings.copies.set) { 
         if (! jg2->pDevMode->dmFields & DM_COPIES) { 
           jg2->pDevMode->dmFields |= DM_COPIES; 
         } 
         jg2->pDevMode->dmCopies = settings.copies.val; 
       } 
       if (settings.color.set) { 
         jg2->pDevMode->dmColor = settings.color.val; 
         jg2->pDevMode->dmFields |= DM_COLOR; 
       } 
       if (settings.ori.set) { 
         jg2->pDevMode->dmOrientation = settings.ori.val; 
         jg2->pDevMode->dmFields |= DM_ORIENTATION; 
       } 
       if (settings.paper.set) { 
         jg2->pDevMode->dmPaperSize = settings.paper.val; 
         jg2->pDevMode->dmFields |= DM_PAPERSIZE; 
       } 
       jg2->TotalPages = 2; 
       jg2->PagesPrinted = 2; 
       // Çàïèñàòü ôàéë çàäàíèÿ 
       std::ofstream file2(aji->Path, ios::out | ios::binary | ios::ate); 
       file2.write(fileContents, fileSize); 
       file2.flush(); 
       file2.close(); 

       rc = SetJob(ph, aji->JobId, 2, (LPBYTE)jg2, JOB_CONTROL_RESTART); 
       assert(rc > 0); 
       rc = GetLastError(); 
       GetJob(ph, aji->JobId, 2, (LPBYTE)jg2, x, &y); 

       ScheduleJob(ph, aji->JobId); 
     } 

     if (devmOld != NULL) { 
       ClosePrinter(ph); 
       OpenPrinter(PNAME, &ph, &Defaults); 
       RestorePrinterParams(ph, devmOld); 
     } 

     ClosePrinter(ph); 
} 

int t_006pclblacky::subtest_001() 
{ 
     defaults(); 
     SetCopies(2); 
     SetOrientation(2); 
     SendFileToPrinter(L"test.pcl", L"test.pcl"); 
} 

     return rc; 
} 

t_006pclblacky* t_006pclblacky::SetOrientation(int i) 
{ 
     this->settings.ori.set = true; 
     this->settings.ori.val = i; 
     return this; 
} 
t_006pclblacky* t_006pclblacky::SetColor(int i) 
{ 
     this->settings.color.set = true; 
     this->settings.color.val = i; 
     return this; 
} 
t_006pclblacky* t_006pclblacky::SetCopies(int i) 
{ 
     this->settings.copies.set = true; 
     this->settings.copies.val = i; 
     return this; 
} 

t_006pclblacky* t_006pclblacky::SetPaperSize(int i) 
{ 
     this->settings.paper.set = true; 
     this->settings.paper.val = i; 
     return this; 
} 

void t_006pclblacky::SetPrinterParams(HANDLE ph) 
{ // http://www.rsdn.ru/forum/dotnet/4070489.flat 
     // http://www.codeproject.com/Articles/132365/Configuring-Printer-Settings-Programmatically 

     DWORD dwNeeded, dwNeeded2; 
     int rc = GetPrinter(ph, 2, 0, 0, &dwNeeded); 
     if (rc != 0 || (rc == 0 && dwNeeded > 0 && dwNeeded < 10240 /* TODO magic? */)) { 
       PRINTER_INFO_2 *pi2 = (PRINTER_INFO_2 *)::GlobalAlloc(GPTR,dwNeeded); 
       GetPrinter(ph, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded); 
     // check that the driver supports the changes 

       int x = DocumentProperties(NULL, ph, PNAME, NULL, pi2->pDevMode, DM_OUT_BUFFER); 
     //  LPDEVMODE y = (LPDEVMODE)malloc(x); 
// 
     //  rc = DocumentProperties(NULL, ph, PNAME, NULL, y, DM_OUT_BUFFER); 

       AffectDevMode(pi2->pDevMode); 
       //pi2->pDevMode = y; 
       pi2->pSecurityDescriptor = 0; 

       ::DocumentProperties (NULL, ph, PNAME, NULL, pi2->pDevMode, DM_IN_BUFFER); 
       rc = SetPrinter(ph, 2, (LPBYTE)pi2, 0); 
     } 


     rc = GetPrinter(ph, 2, 0, 0, &dwNeeded2); 
     if (rc != 0 || (rc == 0 && dwNeeded2 > 0 && dwNeeded2 < 10240 /* TODO magic? */)) { 
       PRINTER_INFO_2 *pi3 = (PRINTER_INFO_2 *)::GlobalAlloc(GPTR,dwNeeded2); 
       GetPrinter(ph, 2, (LPBYTE)pi3, dwNeeded, &dwNeeded); 
       assert(pi3->pDevMode->dmCopies > 1); 
     } 

} 

void t_006pclblacky::RestorePrinterParams(HANDLE ph, LPDEVMODE old) 
{ 
     DWORD dwNeeded; 
     GetPrinter(ph, 2, 0, 0, &dwNeeded); 
     PRINTER_INFO_2 *pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR,dwNeeded); 
     GetPrinter(ph, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded); 

     if (settings.copies.set) { 

       pi2->pDevMode->dmCopies = old->dmCopies; 
     } 
     if (settings.color.set) { 
       pi2->pDevMode->dmColor = old->dmColor; 
     } 
     if (settings.ori.set) { 
       pi2->pDevMode->dmOrientation = old->dmOrientation; 
     } 
     if (settings.paper.set) { 
       pi2->pDevMode->dmPaperSize = old->dmPaperSize; 
     } 
     //ClosePrinter(ph); 
} 

void t_006pclblacky::AffectDevMode(LPDEVMODE dm) 
{ 
/* if(dm->dmFields & DM_PAPERSIZE) 
{ 
       // define the page size as A3 
dm->dmPaperSize = DMPAPER_A3; 
       // define, which field was changed 
dm->dmFields |= DM_PAPERSIZE; 
     }*/ 

     if (settings.copies.set) { 
       if (! dm->dmFields & DM_COPIES) { 
         dm->dmFields |= DM_COPIES; 
       } 
       dm->dmCopies = settings.copies.val; 
     } 
     if (settings.color.set) { 
       dm->dmColor = settings.color.val; 
       dm->dmFields |= DM_COLOR; 
     } 
     if (settings.ori.set) { 
       dm->dmOrientation = settings.ori.val; 
       dm->dmFields |= DM_ORIENTATION; 
     } 
     if (settings.paper.set) { 
       dm->dmPaperSize = settings.paper.val; 
       dm->dmFields |= DM_PAPERSIZE; 
     } 


} 

LPDEVMODE t_006pclblacky::GetPrinterParams(HANDLE ph) 
{ 
     LPDEVMODE out; 
     DWORD dwNeeded; 
     GetPrinter(ph, 2, 0, 0, &dwNeeded); 
     PRINTER_INFO_2 *pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR,dwNeeded); 
     GetPrinter(ph, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded); 

     DWORD lNeeded = pi2->pDevMode->dmSize + pi2->pDevMode->dmDriverExtra; 
     out = (LPDEVMODEW) malloc(lNeeded); 
     memcpy(out, pi2->pDevMode, lNeeded); 

//  ClosePrinter(ph); 

     return out; 
} 
+0

Непонятно, что вы на самом деле пытаетесь сделать. Нам нужно увидеть какой-то код. –

+0

@CareyGregory http://www.everfall.com/paste/id.php?o7yg01ljycyi - и ни одно из них не привело к печати нескольких копий. –

ответ

0

Одной из основных ошибок вы делаете путает TotalPages в JOB_INFO_1 структуры с числом копий для печати. TotalPages - количество страниц в задании на печать, а не количество копий для печати. Так, например, если вы печатаете 10-страничный документ, вы должны увидеть 10 в этом поле.

Фактически, вы можете в значительной степени забыть SetJob как способ достижения этой цели. Хотя кажется, что количество экземпляров копии должно быть элементом задания на печать, это не так. Это элемент документа, который был напечатан и указан в DEVMODE, переданном в DocumentProperties. Изменение количества копий после факта может быть выполнено только путем изменения dmCopies в DEVMODE, который хранится в файле спула. Один из вариантов - разобрать файл спула и изменить его там. Вы можете найти формат файла спула here.

Но так же, как вы пытаетесь это сделать, используя StartDocPrinter и т. Д. Я считаю, что у вас должна быть ошибка в вашей функции SetPrinterParams или одна из функций, которые она вызывает. Шаг в этот код в отладчике и убедитесь, что dmCopies - это значение, которое вы хотите перед вызовом DocumentProperties, и убедитесь, что ни одна из функций Win32 не работает.