1

我需要的是再次重新打印假脱机文件(不是作业*),设置新的份数。

到目前为止,尝试了以下尝试:

  • OpenPrinter、AddJob、SetJob(使用 JOB_INFO_2->pDevMode)
  • OpenPrinter、SetPrinter、DocumentProperties、AddJob、SetJob
  • OpenPrinter、StartDocPrinter、StartPagePrinter、WritePrinter

许多 Clo​​sePrinter 组合和许多 SetPrinter..DocumentProperties 部分的解决方法 - 没有成功。

更改打印机(HP 到 Brother),重新启动后台处理程序和 PC - 无效。

在打印作业列表中可以看到,设置了份数。但是,我从打印机中得到的是一份。

此外,在所有相关情况下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;
} 
4

1 回答 1

0

您犯的一个基本错误是TotalPagesJOB_INFO_1结构中与要打印的副本数混淆。 TotalPages是打印作业中的页数,而不是要打印的份数。因此,例如,如果您打印一个 10 页的文档,您应该期望在此字段中看到 10。

事实上,你几乎可以忘记SetJob作为实现这一点的一种方式。虽然看起来份数应该是打印作业的一个元素,但事实并非如此。它是已打印的文档元素,并在DEVMODE传递给DocumentProperties. 事后更改副本计数只能通过更改存储在假脱机文件中的dmCopies来完成。DEVMODE一种选择是解析假脱机文件并在那里更改值。您可以在此处找到假脱机文件格式。

但是您尝试使用StartDocPrinteretc. 的方式也应该有效。我相信您的SetPrinterParams函数或它调用的函数之一肯定有错误。在调试器中进入该代码,并确保dmCopies在调用之前是您想要的值DocumentProperties,并确保所有 Win32 函数都没有失败。

于 2013-12-11T21:43:34.550 回答