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

📄 emf.c

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

                  goto CleanUp;
              }
          }
       }

       if (bDuplex) {
          if (pHead->pNext && pHead->pNext->pNext) {
              dwEndPage2 = pHead->dwPageNumber - 1;
              pHead = pHead->pNext;
              dwStartPage2 = pHead->dwPageNumber;
              dwEndPage1 = dwStartPage2 - 1;
              pHead = pHead->pNext;
              dwStartPage1 = pHead->dwPageNumber;
          } else {
              break;
          }
       } else {
          pHead = pHead->pNext;
          if (pHead) {
              dwEndPage1 = dwStartPage1 - 1;
              dwStartPage1 = pHead->dwPageNumber;
          }
       }

    }

    bReturn = TRUE;

CleanUp:

    return bReturn;
}

BOOL
PrintOneSideBookletEMF(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwNupBorderFlags,
    DWORD        dwTotalNumberOfPages,
    DWORD        dwTotalPrintPages,
    DWORD        dwStartPage,
    BOOL         bReverseOrderPrinting,
    DWORD        dwOptimization,
    DWORD        dwDuplexMode,
    LPDEVMODE    pDevmode)

/*++
Function Description: PrintOneSideBookletEMF prints one page of the booklet job.

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
            dwTotalNumberOfPages   -- number of pages in the document
            dwTotalPrintPages      -- number of pages to printed (multiple of 4)
            dwStartPage            -- number of the starting page for the side
            bReverseOrderPrinting  -- flag for reverse order printing
            dwOptimization         -- optimization flags
            dwDuplexMode           -- duplex printing mode (none|horz|vert)
            pDevmode               -- devmode with resolution settings

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

{
    DWORD       dwPageArray[4];
    DWORD       dwPagesPrinted = 0, dwPageIndex, dwAngle, dwPageType, dwLastPage;
    HANDLE      hEMF = NULL;
    LPDEVMODEW  pLastDM, pCurrDM;
    BOOL        bReturn = FALSE ,bNewDevmode;

    // set the order of the pages
    if (bReverseOrderPrinting) {
        dwPageArray[0] = dwStartPage + 1;
        dwPageArray[1] = dwTotalPrintPages - dwStartPage;
        if (dwDuplexMode == EMF_DUP_VERT) {
           dwPageArray[2] = dwStartPage;
           dwPageArray[3] = dwPageArray[1] + 1;
        } else { // EMF_DUP_HORZ
           dwPageArray[3] = dwStartPage;
           dwPageArray[2] = dwPageArray[1] + 1;
        }
    } else {
        dwPageArray[1] = dwStartPage;
        dwPageArray[0] = dwTotalPrintPages - dwStartPage + 1;
        if (dwDuplexMode == EMF_DUP_VERT) {
           dwPageArray[2] = dwPageArray[0] - 1;
           dwPageArray[3] = dwPageArray[1] + 1;
        } else { // EMF_DUP_HORZ
           dwPageArray[2] = dwPageArray[1] + 1;
           dwPageArray[3] = dwPageArray[0] - 1;
        }
    }

    // Set page number for ResetDC
    dwLastPage = (dwTotalNumberOfPages < dwPageArray[0]) ? dwTotalNumberOfPages
                                                         : dwPageArray[0];

    // Process devmodes in the spool file
    if (!ResetDCForNewDevmode(hSpoolHandle,
                              hPrinterDC,
                              dwLastPage,
                              FALSE,
                              dwOptimization,
                              &bNewDevmode,
                              pDevmode)) {
        goto CleanUp;
    }

    while (dwPagesPrinted < 4) {
       for (dwPageIndex = 1;
            dwPageIndex <= dwNumberOfPagesPerSide;
            ++dwPageIndex, ++dwPagesPrinted) {

            if (dwPageArray[dwPagesPrinted] <= dwTotalNumberOfPages) {

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

            if (dwPageIndex == 1) {

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

            if (dwPageArray[dwPagesPrinted] <= dwTotalNumberOfPages) {

                 if ((dwDuplexMode == EMF_DUP_VERT) &&
                     (dwPagesPrinted > 1)) {
                      dwAngle = EMF_DEGREE_270;
                 } else { // EMF_DUP_HORZ or 1st side
                      dwAngle = EMF_DEGREE_90;
                 }

                 if (!PlayEMFPage(hSpoolHandle,
                                  hPrinterDC,
                                  hEMF,
                                  dwNumberOfPagesPerSide,
                                  dwPageArray[dwPagesPrinted],
                                  dwPageIndex,
                                  dwNupBorderFlags,
                                  dwAngle)) {

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

            if (dwPageIndex == dwNumberOfPagesPerSide) {

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

    bReturn = TRUE;

CleanUp:

    return bReturn;
}


BOOL
PrintBookletEMF(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwTotalNumberOfPages,
    DWORD        dwNupBorderFlags,
    DWORD        dwJobNumberOfCopies,
    DWORD        dwDrvNumberOfCopies,
    BOOL         bReverseOrderPrinting,
    BOOL         bCollate,
    DWORD        dwOptimization,
    DWORD        dwDuplexMode,
    LPDEVMODEW   pDevmode,
    PPRINTPROCESSORDATA pData)

/*++
Function Description: PrintBookletEMF prints the job in 2-up in booklet form.

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
            dwTotalNumberOfPages   -- 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
            bReverseOrderPrinting  -- flag for reverse order printing
            bCollate               -- flag for collating the copies
            dwOptimization         -- optimization flags
            dwDuplexMode           -- duplex printing mode (none|horz|vert)
            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
--*/

{
    BOOL              bReturn = FALSE;
    DWORD             dwTotalPrintPages, dwNumberOfPhyPages, dwRemainingCopies, dwIndex;

    // Get closest multiple of 4 greater than dwTotalNumberOfPages
    dwTotalPrintPages = dwTotalNumberOfPages - (dwTotalNumberOfPages % 4);
    if (dwTotalPrintPages != dwTotalNumberOfPages) {
        dwTotalPrintPages += 4;
    }
    dwNumberOfPhyPages = (DWORD) dwTotalPrintPages / 4;

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

         if (bCollate) {

            if (!PrintOneSideBookletEMF(hSpoolHandle,
                                        hPrinterDC,
                                        dwNumberOfPagesPerSide,
                                        dwNupBorderFlags,
                                        dwTotalNumberOfPages,
                                        dwTotalPrintPages,
                                        dwIndex * 2 + 1,
                                        bReverseOrderPrinting,
                                        dwOptimization,
                                        dwDuplexMode,
                                        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 (!PrintOneSideBookletEMF(hSpoolHandle,
                                            hPrinterDC,
                                            dwNumberOfPagesPerSide,
                                            dwNupBorderFlags,
                                            dwTotalNumberOfPages,
                                            dwTotalPrintPages,
                                            dwIndex * 2 + 1,
                                            bReverseOrderPrinting,
                                            dwOptimization,
                                            dwDuplexMode,
                                            pDevmode)) {
                     goto CleanUp;
                }
            }
         }
    }

    bReturn = TRUE;

CleanUp:

    return bReturn;
}

BOOL
PrintEMFSingleCopy(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    BOOL         bReverseOrderPrinting,
    DWORD        dwDrvNumberOfPagesPerSide,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwTotalNumberOfPages,
    DWORD        dwNupBorderFlags,
    DWORD        dwJobNumberOfCopies,
    DWORD        dwDrvNumberOfCopies,
    BOOL         bCollate,
    BOOL         bOdd,
    BOOL         bBookletPrint,
    DWORD        dwOptimization,
    DWORD        dwDuplexMode,
    LPDEVMODEW   pDevmode,
    PPAGE_NUMBER pHead,
    PPRINTPROCESSORDATA pData)

/*++
Function Description: PrintEMFSingleCopy plays one copy of the job on hPrinterDC.

Parameters: hSpoolHandle           -- handle the spool file handle
            hPrinterDC             -- handle to the printer device context
            bReverseOrderPrinting  -- flag for reverse order printing
            dwDrvNumberOfPagesPerSide -- number of pages the driver will print per side
            dwNumberOfPagesPerSide -- number of pages to be printed per side by the print
                                       processor
            dwTotalNumberOfPages   -- 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
            bOdd                   -- flag to indicate odd number of sides to print
            bBookletPrint          -- flag for booklet printing
            dwOptimization         -- optimization flags
            dwDuplexMode           -- duplex printing mode (none|horz|vert)
            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
--*/

{
    BOOL  bDuplex = (dwDuplexMode != EMF_DUP_NONE);

    if (bBookletPrint) {

       // Booklet Printing
       return PrintBookletEMF(hSpoolHandle,
                              hPrinterDC,
                              dwNumberOfPagesPerSide,
                              dwTotalNumberOfPages,
                              dwNupBorderFlags,
                              dwJobNumberOfCopies,
                              dwDrvNumberOfCopies,
                              bReverseOrderPrinting,
                              bCollate,
                              dwOptimization,
                              dwDuplexMode,
                              pDevmode,
                              pData);
    }

    if (bReverseOrderPrinting) {
       if (dwDrvNumberOfPagesPerSide != 1 || dwNumberOfPagesPerSide == 1) {

          return PrintReverseForDriverEMF(hSpoolHandle,
                                          hPrinterDC,
                                          dwDrvNumberOfPagesPerSide,
                                          dwTotalNumberOfPages,

⌨️ 快捷键说明

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