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

📄 emf.cpp

📁 Separator Print Processor Sample
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // 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) &&
               IS_DMSIZE_VALID(pDevmode, dmCollate) && 
               (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,
                                           NULL)) {
                 }
             }

             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:

    return bReturn;
}



BOOL
PrintReverseForDriverEMF(
    HANDLE     hSpoolHandle,
    HDC        hPrinterDC,
    DWORD      dwDrvNumberOfPagesPerSide,
    DWORD      dwTotalNumberOfPages,
    DWORD      dwNupBorderFlags,
    DWORD      dwJobNumberOfCopies,
    DWORD      dwDrvNumberOfCopies,
    BOOL       bCollate,
    BOOL       bDuplex,
    BOOL       bOdd,
    DWORD      dwOptimization,
    LPDEVMODEW pDevmode,
    PPAGE_NUMBER pHead,
    PPRINTPROCESSORDATA pData)

/*++
Function Description: PrintReverseForDriverEMF plays the EMF pages 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
            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 to indicate duplex printing
            bOdd                   -- flag to indicate odd number of sides to print
            dwOptimization         -- optimization flags
            pDevmode               -- pointer to devmode for changing the copy count
            pHead                  -- pointer to a linked list containing the starting
                                       page numbers for each of the sides
            pData                  -- needed for status and the handle of the event: pause, resume etc.                                     

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

{
    DWORD         dwPageNumber,dwRemainingCopies;
    BOOL          bReturn = FALSE;

    // select the correct page for duplex printing
    if (bDuplex && !bOdd) {
       if (pHead) {
          pHead = pHead->pNext;
       } else {
          bReturn = TRUE;
          goto CleanUp;
       }
    }

    // play the sides in reverse order
    while (pHead) {
        //
        // If the print processor is paused, wait for it to be resumed
        //
        if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
            WaitForSingleObject(pData->semPaused, INFINITE);
        }
        
        // set the page number
        dwPageNumber = pHead->dwPageNumber;

        if (bCollate) {
       
           if (!PrintOneSideReverseForDriverEMF(hSpoolHandle,
                                                hPrinterDC,
                                                dwDrvNumberOfPagesPerSide,
                                                dwTotalNumberOfPages,
                                                dwNupBorderFlags,
                                                bDuplex,
                                                dwOptimization,
                                                dwPageNumber,
                                                pDevmode)) {
               goto CleanUp;
           }
           
        } else {

           dwRemainingCopies = dwJobNumberOfCopies;

           while (dwRemainingCopies) {

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

               if (!PrintOneSideReverseForDriverEMF(hSpoolHandle,
                                                    hPrinterDC,
                                                    dwDrvNumberOfPagesPerSide,
                                                    dwTotalNumberOfPages,
                                                    dwNupBorderFlags,
                                                    bDuplex,
                                                    dwOptimization,
                                                    dwPageNumber,
                                                    pDevmode)) {
                   goto CleanUp;
               }
           }
        }

        pHead = pHead->pNext;

        // go to the next page for duplex printing
        if (bDuplex && pHead) {
            pHead = pHead->pNext;
        }
    }

    bReturn = TRUE;

CleanUp:

    return bReturn;
}

BOOL
PrintOneSideReverseEMF(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwNupBorderFlags,
    BOOL         bDuplex,
    DWORD        dwOptimization,
    DWORD        dwStartPage1,
    DWORD        dwEndPage1,
    DWORD        dwStartPage2,
    DWORD        dwEndPage2,
    LPDEVMODE    pDevmode)

/*++
Function Description: PrintOneSideReverseEMF plays the EMF pages for the next physical page.

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
            dwNupBorderFlags       -- border printing options for nup
            bDuplex                -- flag to indicate duplex printing
            dwOptimization         -- optimization flags
            dwStartPage1           -- page number of the first EMF page on 1st side
            dwEndPage1             -- page number of the last EMF page on 1st side
            dwStartPage2           -- page number of the first EMF page on 2nd side
            dwEndPage2             -- page number of the last EMF page on 2nd side
            pDevmode               -- devmode with resolution settings

Return Values:  TRUE if successful
                FALSE otherwise
--*/
{
    DWORD         dwPageNumber, dwPageIndex, dwPageType;
    BOOL          bReturn = FALSE, bNewDevmode;
    LPDEVMODEW    pCurrDM;
    HANDLE        hEMF = NULL;
    DWORD         dwEndPage, dwStartPage, dwSides, dwAngle;
    INT           dmOrientation = pDevmode->dmOrientation;

    for (dwSides = bDuplex ? 2 : 1; 
         dwSides; 
         --dwSides) {

         if (bDuplex && (dwSides == 1)) {
             dwStartPage = dwStartPage2;
             dwEndPage = dwEndPage2;
         } else {
             dwStartPage = dwStartPage1;
             dwEndPage = dwEndPage1;
         }

         for (dwPageNumber = dwStartPage, dwPageIndex = 1;
              dwPageNumber <= dwEndPage;
              ++dwPageNumber, ++dwPageIndex) {

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

                ODS(("GdiGetPageHandle failed\nPrinter %ws\n", pDevmode->dmDeviceName));
                goto CleanUp;                      
            }
            dwAngle = EMF_DEGREE_90;
            if (dwPageIndex == 1) {
                   
                // Process devmodes in the spool file and call StartPage
                if (!ResetDCForNewDevmode(hSpoolHandle,
                                             hPrinterDC,
                                             dwPageNumber,
                                             FALSE,
                                             dwOptimization,
                                             &bNewDevmode,
                                             pDevmode,
                                             &pCurrDM) ||

                       !GdiStartPageEMF(hSpoolHandle)) {
                        
                       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;
                    }
                }
            }

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

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

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

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

    bReturn = TRUE;

CleanUp:

    return bReturn;
}

BOOL
PrintReverseEMF(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwTotalNumberOfPages,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwNupBorderFlags,
    DWORD        dwJobNumberOfCopies,
    DWORD        dwDrvNumberOfCopies,
    BOOL         bCollate,
    BOOL         bDuplex,
    BOOL         bOdd,
    DWORD        dwOptimization,
    LPDEVMODEW   pDevmode,
    PPAGE_NUMBER pHead,
    PPRINTPROCESSORDATA pData)

/*++
Function Description: PrintReverseEMF plays the EMF pages in the reverse order and also
                      performs nup transformations.

Parameters: hSpoolHandle           -- handle the spool file handle
            hPrinterDC             -- handle to the printer device context
            dwTotalNumberOfPages   -- number of pages in the document
            dwNumberOfPagesPerSide -- number of pages to be printed per side by the print
                                       processor
            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 to indicate duplex printing
            bOdd                   -- flag to indicate odd number of sides to print
            dwOptimization         -- optimization flags
            pDevmode               -- pointer to devmode for changing the copy count
            pHead                  -- pointer to a linked list containing the starting

⌨️ 快捷键说明

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