⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 emf.c

📁 用delphi开发的有关打印的驱动实例; LIBRARY genprint EXPORTS EnumPrintProcessorDatatypesW OpenPrintProc
💻 C
📖 第 1 页 / 共 5 页
字号:
    DWORD              cPagesToPlay;

    // set the number of sides on this page;
    dwSides = bDuplex ? 2 : 1;
    *pbComplete = FALSE;

    for ( ; dwSides && !*pbComplete ; --dwSides) {

       // loop for a single side
       for (dwPageIndex = 1;
            dwPageIndex <= dwNumberOfPagesPerSide;
            ++dwPageIndex, ++dwPageNumber) {

            if (!(hEMF = GdiGetPageHandle(hSpoolHandle,
                                          dwPageNumber,
                                          &dwPageType))) {

                if (GetLastError() == ERROR_NO_MORE_ITEMS) {
                     // End of the print job
                     *pbComplete = TRUE;
                     break;
                }

                ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
                goto CleanUp;
            }

            // Process new devmodes in the spool file that appear before this page
            if (!ResetDCForNewDevmode(hSpoolHandle,
                                      hPrinterDC,
                                      dwPageNumber,
                                      (dwPageIndex != 1),
                                      dwOptimization,
                                      &bNewDevmode,
                                      pDevmode)) {

                goto CleanUp;
            }

            // Reset page index if new page was started
            if (bNewDevmode) {
                dwPageIndex = 1;
            }

            // Call StartPage for each new page
            if ((dwPageIndex == 1) &&
                !GdiStartPageEMF(hSpoolHandle)) {

                ODS(("StartPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
                goto CleanUp;
            }

            if (!PlayEMFPage(hSpoolHandle,
                             hPrinterDC,
                             hEMF,
                             dwNumberOfPagesPerSide,
                             dwPageNumber,
                             dwPageIndex,
                             dwNupBorderFlags,
                             EMF_DEGREE_90)) {

                ODS(("PlayEMFPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
                goto CleanUp;
            }
       }

       //
       // Explaination of the scinario set for the conditions on
       // dwPageIndex1 , pbComplete and bDuplex.
       // N.B. we are naming them cond.1 and cond.2
       //     dwPageIndex!=1    pbComplete   bDuplex    Condition
       //           0               0           0       None
       //           0               0           1       None
       //           0               1           0       None
       //           0               1           1       Cond2 on Second Side i.e. dwsides==1
       //           1               0           0       Cond1
       //           1               0           1       Cond1
       //           1               1           0       Cond1
       //           1               1           1       Cond1 & Cond2 on First Side i.e. dwsides==2
       //


       // cond.1
       if (dwPageIndex != 1) {

           // Call EndPage if we played any pages
           if (!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {

               ODS(("EndPage failed\n"));
               *pbComplete = FALSE;
               goto CleanUp;
           }
       }

       // cond.2
       // play empty page on the back of duplex
       if (*pbComplete && bDuplex && dwDrvNumberOfPagesPerSide==1) {

           ODS(("PCL or PS with no N-up\n"));

           //
           // Checking dwsides against 2 or 1.
           // depends on whether it is n-up or not.
           //
           if (((dwPageIndex!=1)?(dwSides==2):(dwSides==1))) {

               if (!GdiStartPageEMF(hSpoolHandle) ||
                   !GdiEndPageEMF(hSpoolHandle, dwOptimization)) {

                   ODS(("EndPage failed\n"));
                   *pbComplete = FALSE;
                   goto CleanUp;
               }
           }
        }
    }


    if (*pbComplete &&
        dwNumberOfPagesPerSide==1 &&
        dwDrvNumberOfPagesPerSide!=1 &&
        bDuplex &&
        (dwPageNumber-1)%(2*dwDrvNumberOfPagesPerSide))
    {
        //
        // Number of pages played on last phisical page
        //
        cPagesToPlay = 2*dwDrvNumberOfPagesPerSide - (dwPageNumber-1)%(2*dwDrvNumberOfPagesPerSide);

        ODS(("\nPS with N-up!\nMust fill in %u pages\n", cPagesToPlay));

        for (;cPagesToPlay;cPagesToPlay--)
        {
            if (!GdiStartPageEMF(hSpoolHandle) || !GdiEndPageEMF(hSpoolHandle, dwOptimization))
            {
                ODS(("EndPage failed\n"));
                goto CleanUp;
            }
        }
    }


    if (!(*pbComplete)) dwReturn = dwPageNumber;

CleanUp:

    return dwReturn;
}

BOOL
PrintForwardEMF(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwDrvNumberOfPagesPerSide,
    DWORD        dwNupBorderFlags,
    DWORD        dwJobNumberOfCopies,
    DWORD        dwDrvNumberOfCopies,
    BOOL         bCollate,
    BOOL         bDuplex,
    DWORD        dwOptimization,
    LPDEVMODEW   pDevmode,
    PPRINTPROCESSORDATA pData)

/*++
Function Description: PrintForwardEMF plays the EMF files in the order in which they
                      were spooled.

Parameters: hSpoolHandle              -- handle the spool file handle
            hPrinterDC                -- handle to the printer device context
            dwNumberOfPagesPerSide    -- number of pages to be printed per side by the print processor
            dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
            dwNupBorderFlags          -- border printing options for nup
            dwJobNumberOfCopies       -- number of copies of the job to be printed
            dwDrvNumberOfCopies       -- number of copies that the driver can print
            bCollate                  -- flag for collating the copies
            bDuplex                   -- flag for duplex printing
            dwOptimization            -- optimization flags
            pDevmode                  -- pointer to devmode for changing the copy count
            pData                     -- needed for status and the handle of the event: pause, resume etc.

Return Values:  TRUE if successful
                FALSE otherwise
--*/

{
    DWORD              dwLastPageNumber = 1,dwPageNumber,dwPageIndex,dwRemainingCopies;
    BOOL               bReturn = FALSE;

    // Keep printing as long as the spool file contains EMF handles.
    while (dwLastPageNumber) {

        //
        // If the print processor is paused, wait for it to be resumed
        //
        if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
            WaitForSingleObject(pData->semPaused, INFINITE);
        }

        dwPageNumber = dwLastPageNumber;

        if (bCollate) {

           dwLastPageNumber = PrintOneSideForwardEMF(hSpoolHandle,
                                                     hPrinterDC,
                                                     dwNumberOfPagesPerSide,
                                                     dwDrvNumberOfPagesPerSide,
                                                     dwNupBorderFlags,
                                                     bDuplex,
                                                     dwOptimization,
                                                     dwPageNumber,
                                                     &bReturn,
                                                     pDevmode);
        } else {

           dwRemainingCopies = dwJobNumberOfCopies;

           while (dwRemainingCopies) {

               if (dwRemainingCopies <= dwDrvNumberOfCopies) {
                  SetDrvCopies(hPrinterDC, pDevmode, dwRemainingCopies);
                  dwRemainingCopies = 0;
               } else {
                  SetDrvCopies(hPrinterDC, pDevmode, dwDrvNumberOfCopies);
                  dwRemainingCopies -= dwDrvNumberOfCopies;
               }

               //
               // If the print processor is paused, wait for it to be resumed
               //
               if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
                    WaitForSingleObject(pData->semPaused, INFINITE);
               }

               if (!(dwLastPageNumber =  PrintOneSideForwardEMF(hSpoolHandle,
                                                                hPrinterDC,
                                                                dwNumberOfPagesPerSide,
                                                                dwDrvNumberOfPagesPerSide,
                                                                dwNupBorderFlags,
                                                                bDuplex,
                                                                dwOptimization,
                                                                dwPageNumber,
                                                                &bReturn,
                                                                pDevmode)) &&
                   !bReturn) {

                    goto CleanUp;
               }
           }
        }
    }

CleanUp:

    return bReturn;
}

BOOL
PrintOneSideReverseForDriverEMF(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwDrvNumberOfPagesPerSide,
    DWORD        dwTotalNumberOfPages,
    DWORD        dwNupBorderFlags,
    BOOL         bDuplex,
    DWORD        dwOptimization,
    DWORD        dwPageNumber,
    LPDEVMODE    pDevmode)

/*++
Function Description: PrintOneSideReverseForDriverEMF plays the EMF pages on the next
                      physical page, in the reverse order for the driver which does the
                      Nup transformations.

Parameters: hSpoolHandle           -- handle the spool file handle
            hPrinterDC             -- handle to the printer device context
            dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
            dwTotalNumberOfPages   -- total number of pages in the document
            dwNupBorderFlags       -- border printing options for nup
            bDuplex                -- flag to indicate duplex printing
            dwOptimization         -- optimization flags
            dwPageNumber           -- page number to start the side
            pDevmode               -- devmode with resolution settings

Return Values:  TRUE if successful
                FALSE otherwise
--*/
{
    DWORD       dwPageIndex, dwPageType, dwSides;
    BOOL        bReturn = FALSE, bNewDevmode,BeSmart;
    LPDEVMODEW  pLastDM,pCurrDM;
    HANDLE      hEMF = NULL;
    DWORD       dwLimit;

    dwSides = bDuplex ? 2 : 1;

    //
    // If the document will fit on one phisical page, then this variable will prevent
    // the printer from playing extra pages just to fill in one phisical page
    // The exception is when the pages fit on a single phisical page, but they must
    // be collated. Then because of design, the printer will also draw borders for the
    // empty pages which are played so that the page gets ejected.
    //
    BeSmart =  (dwTotalNumberOfPages<=dwDrvNumberOfPagesPerSide) &&
               (pDevmode->dmCollate != DMCOLLATE_TRUE);

    for (; dwSides; --dwSides) {

       // This loop may play some empty pages in the last side, since the
       // driver is doing nup and it does not keep count of the page numbers
       //
       dwPageIndex=BeSmart?dwPageNumber:1;
       dwLimit    =BeSmart?dwTotalNumberOfPages:dwDrvNumberOfPagesPerSide;

       for (;dwPageIndex<=dwLimit; ++dwPageIndex,++dwPageNumber) {

             if (BeSmart || dwPageNumber <= dwTotalNumberOfPages) {

                 if (!(hEMF = GdiGetPageHandle(hSpoolHandle,
                                               dwPageNumber,
                                               &dwPageType))) {
                     ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
                     goto CleanUp;
                 }

                 // Process new devmodes in the spoolfile
                 if (!ResetDCForNewDevmode(hSpoolHandle,
                                           hPrinterDC,
                                           dwPageNumber,
                                           FALSE,
                                           dwOptimization,
                                           &bNewDevmode,
                                           pDevmode)) {
                 }
             }

             if (!GdiStartPageEMF(hSpoolHandle)) {
                 ODS(("StartPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
                 goto CleanUp;
             }

             if (BeSmart || dwPageNumber <= dwTotalNumberOfPages) {
                if (!PlayEMFPage(hSpoolHandle,
                                  hPrinterDC,
                                  hEMF,
                                  1,
                                  dwPageNumber,
                                  1,
                                  dwNupBorderFlags,
                                  EMF_DEGREE_90)) {

                     ODS(("PlayEMFPage failed\n"));
                     goto CleanUp;
                 }
             }

             if (!GdiEndPageEMF(hSpoolHandle, dwOptimization)) {
                 ODS(("EndPage failed\nPrinter %ws\n", pDevmode->dmDeviceName));
                 goto CleanUp;
             }
       }
    }

    bReturn = TRUE;

CleanUp:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -