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

📄 emf.cpp

📁 Separator Print Processor Sample
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                else
                {
                    pCurrDM->dmCollate = DMCOLLATE_FALSE;
                }
                
            }
        }

        // Ignore the return values of ResetDC and SetGraphicsMode
        GdiResetDCEMF(hSpoolHandle, pCurrDM);
        SetGraphicsMode(hPrinterDC, GM_ADVANCED);       
    }

    bReturn = TRUE;

    return bReturn;
}

DWORD
PrintOneSideForwardEMF(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwDrvNumberOfPagesPerSide,
    DWORD        dwNupBorderFlags,
    BOOL         bDuplex,
    DWORD        dwOptimization,
    DWORD        dwPageNumber,
    DWORD        dwJobNumberOfCopies,
    LPBOOL       pbComplete,
    LPDEVMODE    pDevmode)

/*++
Function Description: PrintOneSideForwardEMF plays the next physical page in the same order
                      as the spool file.

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
            bDuplex                   -- flag to indicate duplex printing
            dwOptimization            -- optimization flags
            dwPageNumber              -- pointer to the starting page number
            pbComplete                -- pointer to the flag to indicate completion
            pDevmode                  -- devmode with resolution settings
   
Return Values:  Last Page Number if successful
                0 on job completion (pbReturn set to TRUE) and
                  on failure (pbReturn remains FALSE)
--*/

{
    DWORD              dwPageIndex, dwPageType;
    DWORD              dwReturn = 0;
    LPDEVMODEW         pCurrDM;
    HANDLE             hEMF = NULL;
    DWORD              dwSides;
    BOOL               bNewDevmode;
    DWORD              cPagesToPlay;
    DWORD              dwAngle;
    INT                dmOrientation = pDevmode->dmOrientation;

    // 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;
            }
            dwAngle = EMF_DEGREE_90;
            if (dwPageIndex == 1)
            {
                // Process new devmodes in the spool file that appear before this page
                if (!ResetDCForNewDevmode(hSpoolHandle,
                                      hPrinterDC,
                                      dwPageNumber,
                                      (dwPageIndex != 1),
                                      dwOptimization,
                                      &bNewDevmode,
                                      pDevmode,
                                      &pCurrDM)) {

                    goto CleanUp;
                }
                if (pCurrDM)
                    dmOrientation = pCurrDM->dmOrientation;
            }
            // in case of orientation switch we need to keep track of what
            // we started with and what it is now
            else if (dwNumberOfPagesPerSide > 1)
            {
                if (GdiGetDevmodeForPagePvt(hSpoolHandle, 
                              dwPageNumber,
                              &pCurrDM,
                              NULL))
                {
                    if (pCurrDM && pCurrDM->dmOrientation != dmOrientation)
                    {
                        dwAngle = EMF_DEGREE_SWAP | EMF_DEGREE_90;
                    }
                }
            }
            // 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,
                             dwAngle)) {

                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 && 
        dwJobNumberOfCopies!=1)
    {
        cPagesToPlay = dwDrvNumberOfPagesPerSide * (bDuplex ? 2 : 1);
        if ((dwPageNumber-1) % cPagesToPlay)
        {
            //
            // Number of pages played on last physical page
            //
            cPagesToPlay = cPagesToPlay - ((dwPageNumber-1) % cPagesToPlay);

            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,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,
                                                     dwJobNumberOfCopies,
                                                     &bReturn,
                                                     pDevmode);
        } else {

           dwRemainingCopies = dwJobNumberOfCopies;

           while (dwRemainingCopies) {

               if (dwRemainingCopies <= dwDrvNumberOfCopies) {
                  SetDrvCopies(hPrinterDC, pDevmode, dwRemainingCopies);
                  dwRemainingCopies = 0;
               } else {
                  SetDrvCopies(hPrinterDC, pDevmode, dwDrvNumberOfCopies);
                  dwRemainingCopies -= dwDrvNumberOfCopies;
               }
               
               if (!(dwLastPageNumber =  PrintOneSideForwardEMF(hSpoolHandle,
                                                                hPrinterDC,
                                                                dwNumberOfPagesPerSide,
                                                                dwDrvNumberOfPagesPerSide,
                                                                dwNupBorderFlags,
                                                                bDuplex,
                                                                dwOptimization,
                                                                dwPageNumber,
                                                                dwJobNumberOfCopies,
                                                                &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;
    HANDLE      hEMF = NULL;
    DWORD       dwLimit;

    dwSides = bDuplex ? 2 : 1;

    //

⌨️ 快捷键说明

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