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

📄 emf.c

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

    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         dwPageIndex,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    pLastDM,pCurrDM;
    HANDLE        hEMF = NULL;
    DWORD         dwEndPage, dwStartPage, dwSides;

    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;
               }

               if (dwPageIndex == 1) {

                   // Process devmodes in the spool file and call StartPage
                   if (!ResetDCForNewDevmode(hSpoolHandle,
                                             hPrinterDC,
                                             dwPageNumber,
                                             FALSE,
                                             dwOptimization,
                                             &bNewDevmode,
                                             pDevmode) ||

                       !GdiStartPageEMF(hSpoolHandle)) {

                       goto CleanUp;
                   }
               }

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

                   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
                                       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,dwPageIndex,dwRemainingCopies;
    DWORD         dwStartPage1,dwStartPage2,dwEndPage1,dwEndPage2;
    BOOL          bReturn = FALSE;

    if (!pHead) {
        bReturn = TRUE;
        goto CleanUp;
    }

    // set the start and end page numbers for duplex and regular printing
    if (bDuplex) {
       if (bOdd) {
           dwStartPage1 = pHead->dwPageNumber;
           dwEndPage1   = dwTotalNumberOfPages;
           dwStartPage2 = dwTotalNumberOfPages+1;
           dwEndPage2   = 0;
       } else {
           dwStartPage2 = pHead->dwPageNumber;
           dwEndPage2   = dwTotalNumberOfPages;

           if (pHead = pHead->pNext) {
               dwStartPage1 = pHead->dwPageNumber;
               dwEndPage1   = dwStartPage2 - 1;
           }
       }
    } else {
       dwStartPage1 = pHead->dwPageNumber;
       dwEndPage1   = dwTotalNumberOfPages;
       dwStartPage2 = 0;
       dwEndPage2   = 0;
    }

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

       if (bCollate) {

          if (!PrintOneSideReverseEMF(hSpoolHandle,
                                      hPrinterDC,
                                      dwNumberOfPagesPerSide,
                                      dwNupBorderFlags,
                                      bDuplex,
                                      dwOptimization,
                                      dwStartPage1,
                                      dwEndPage1,
                                      dwStartPage2,
                                      dwEndPage2,
                                      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 (!PrintOneSideReverseEMF(hSpoolHandle,
                                          hPrinterDC,
                                          dwNumberOfPagesPerSide,
                                          dwNupBorderFlags,
                                          bDuplex,
                                          dwOptimization,
                                          dwStartPage1,
                                          dwEndPage1,
                                          dwStartPage2,

⌨️ 快捷键说明

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