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

📄 emf.c

📁 用delphi开发的有关打印的驱动实例; LIBRARY genprint EXPORTS EnumPrintProcessorDatatypesW OpenPrintProc
💻 C
📖 第 1 页 / 共 5 页
字号:
       rectDocument->bottom -= (LONG) (dYbottom * lYNewPhyPage);
    }

    if (xResolution!=yResolution)
    {
        rectDocument->left   = rectDocument->left   / yResolution;
        rectDocument->right  = rectDocument->right  / yResolution;
        rectDocument->top    = rectDocument->top    / xResolution;
        rectDocument->bottom = rectDocument->bottom / xResolution;
    }

    return;
}

BOOL
PlayEMFPage(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    HANDLE       hEMF,
    DWORD        dwNumberOfPagesPerSide,
    DWORD        dwPageNumber,
    DWORD        dwPageIndex,
    DWORD        dwNupBorderFlags,
    DWORD        dwAngle)

/*++
Function Description: PlayEMFPage plays the EMF in the appropriate rectangle. It performs
                      the required scaling, rotation and translation.

Parameters:   hSpoolHandle           -- handle the spool file handle
              hPrinterDC             -- handle to the printer device context
              hEMF                   -- handle to the contents of the page in the spool file
              dwNumberOfPagesPerSide -- number of pages to be printed per side
              dwPageNumber           -- page number in the document
              dwPageIndex            -- page number in the side. (1 based)
              dwNupBorderFlags       -- border printing options for nup
              dwAngle                -- angle for rotation (if neccesary)

Return Values:  TRUE if successful
                FALSE otherwise
--*/
{
   BOOL         bReturn = FALSE, bRotate;
   RECT         rectDocument, rectPrinter, rectBorder = {-1, -1, -1, -1};
   RECT         *prectClip = NULL;
   XFORM        TransXForm = {1, 0, 0, 1, 0, 0}, RotateXForm = {0, -1, 1, 0, 0, 0};
   HPEN         hPen;
   HANDLE       hFormEMF;
   DWORD        dwPageType,dwFormPage;

   // Compute the rectangle for one page.
   GetPageCoordinatesForNUp(hPrinterDC,
                            &rectDocument,
                            &rectBorder,
                            dwNumberOfPagesPerSide,
                            dwPageIndex,
                            dwNupBorderFlags,
                            &bRotate);

   if (dwAngle == EMF_DEGREE_270) {
       RotateXForm.eM12 = 1;
       RotateXForm.eM21 = -1;
   }   // EMF_DEGREE_90 case is the initialization

   if (bRotate) {

       rectPrinter.top = 0;
       rectPrinter.bottom = rectDocument.right - rectDocument.left;
       rectPrinter.left = 0;
       rectPrinter.right = rectDocument.bottom - rectDocument.top;

       // Set the translation matrix
       if (dwAngle == EMF_DEGREE_270) {
           TransXForm.eDx = (float) rectDocument.right;
           TransXForm.eDy = (float) rectDocument.top;
       } else {
           // EMF_DEGREE_90
           TransXForm.eDx = (float) rectDocument.left;
           TransXForm.eDy = (float) rectDocument.bottom;
       }

       // Set the transformation matrix
       if (!SetWorldTransform(hPrinterDC, &RotateXForm) ||
           !ModifyWorldTransform(hPrinterDC, &TransXForm, MWT_RIGHTMULTIPLY)) {

            ODS(("Setting transformation matrix failed\n"));
            goto CleanUp;
       }
   }

   // Add clipping for Nup
   if (dwNumberOfPagesPerSide != 1) {

       prectClip = &rectDocument;
   }

   // Print the page.
   if (bRotate) {
       GdiPlayPageEMF(hSpoolHandle, hEMF, &rectPrinter, &rectBorder, prectClip);
   } else {
       GdiPlayPageEMF(hSpoolHandle, hEMF, &rectDocument, &rectBorder, prectClip);
   }

   bReturn = TRUE;

CleanUp:

   if (!ModifyWorldTransform(hPrinterDC, NULL, MWT_IDENTITY)) {

       ODS(("Setting Identity Transformation failed\n"));
       bReturn = FALSE;
   }

   return bReturn;
}

BOOL
SetDrvCopies(
    HDC          hPrinterDC,
    LPDEVMODEW   pDevmode,
    DWORD        dwNumberOfCopies)

/*++
Function Description: SetDrvCopies sets the dmCopies field in pDevmode and resets
                      hPrinterDC with this devmode

Parameters: hPrinterDC             -- handle to the printer device context
            pDevmode               -- pointer to devmode
            dwNumberOfCopies       -- value for dmCopies

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

{
    BOOL     bReturn;
    DWORD    dmFields;

    if ((pDevmode->dmFields & DM_COPIES) &&
        (pDevmode->dmCopies == (short) dwNumberOfCopies)) {

         return TRUE;
    }

    // Save the old fields structure
    dmFields = pDevmode->dmFields;
    pDevmode->dmFields |= DM_COPIES;
    pDevmode->dmCopies = (short) dwNumberOfCopies;

    if (!ResetDC(hPrinterDC, pDevmode))  {
        bReturn = FALSE;
    } else {
        bReturn = TRUE;
    }
    // Restore the fields structure
    pDevmode->dmFields = dmFields;

    if (!SetGraphicsMode(hPrinterDC,GM_ADVANCED)) {
        ODS(("Setting graphics mode failed\n"));
        bReturn = FALSE;
    }

    return bReturn;
}

BOOL
DifferentDevmodes(
    LPDEVMODE    pDevmode1,
    LPDEVMODE    pDevmode2
    )

/*++
Function Description: Compares the devmodes for differences other than dmTTOption

Parameters:  pDevmode1    -   devmode 1
             pDevmode2    -   devmode 2

Return Values: TRUE if different ; FALSE otherwise
--*/

{
    DWORD   dwSize1, dwSize2, dwTTOffset, dwSpecOffset, dwLogOffset;

    // Same pointers are the same devmode
    if (pDevmode1 == pDevmode2) {
        return FALSE;
    }

    // Check for Null devmodes
    if (!pDevmode1 || !pDevmode2) {
        return TRUE;
    }

    dwSize1 = pDevmode1->dmSize + pDevmode1->dmDriverExtra;
    dwSize2 = pDevmode2->dmSize + pDevmode2->dmDriverExtra;

    // Compare devmode sizes
    if (dwSize1 != dwSize2) {
        return TRUE;
    }

    dwTTOffset = FIELD_OFFSET(DEVMODE, dmTTOption);
    dwSpecOffset = FIELD_OFFSET(DEVMODE, dmSpecVersion);
    dwLogOffset = FIELD_OFFSET(DEVMODE, dmLogPixels);

    if (wcscmp(pDevmode1->dmDeviceName,
               pDevmode2->dmDeviceName)) {
        // device names are different
        return TRUE;
    }

    if (dwTTOffset < dwSpecOffset ||
        dwSize1 < dwLogOffset) {

        // incorrent devmode offsets
        return TRUE;
    }

    if (memcmp((LPBYTE) pDevmode1 + dwSpecOffset,
               (LPBYTE) pDevmode2 + dwSpecOffset,
               dwTTOffset - dwSpecOffset)) {
        // Front half is different
        return TRUE;
    }

    // Ignore the dmTTOption setting.

    if ((pDevmode1->dmCollate != pDevmode2->dmCollate) ||
        wcscmp(pDevmode1->dmFormName, pDevmode2->dmFormName)) {

        // form name or collate option is different
        return TRUE;
    }

    if (memcmp((LPBYTE) pDevmode1 + dwLogOffset,
               (LPBYTE) pDevmode2 + dwLogOffset,
               dwSize1 - dwLogOffset)) {
        // Back half is different
        return TRUE;
    }

    return FALSE;
}


BOOL
ResetDCForNewDevmode(
    HANDLE       hSpoolHandle,
    HDC          hPrinterDC,
    DWORD        dwPageNumber,
    BOOL         bInsidePage,
    DWORD        dwOptimization,
    LPBOOL       pbNewDevmode,
    LPDEVMODE    pDevmode
    )

/*++
Function Description: Determines if the devmode for the page is different from the
                      current devmode for the printer dc and resets the dc if necessary.
                      The parameters allow dmTTOption to be ignored in devmode comparison.

Parameters: hSpoolHandle         -  spool file handle
            hPrinterDC           -  printer dc
            dwPageNumber         -  page number before which we search for the devmode
            bInsidePage          -  flag to ignore changes in TT options and call EndPage
                                       before ResetDC
            dwOptimization       -  optimization flags
            pbNewDevmode         -  pointer to flag to indicate if ResetDC was called
            pDevmode             -  devmode containing changed resolution settings

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

{
    BOOL           bReturn = FALSE;
    LPDEVMODE      pLastDM, pCurrDM;

    // Initialize OUT parameters
    *pbNewDevmode = FALSE;

    // Get the devmode just before the page
    if (!GdiGetDevmodeForPage(hSpoolHandle,
                              dwPageNumber,
                              &pCurrDM,
                              &pLastDM)) {

        ODS(("GdiGetDevmodeForPage failed\n"));
        return bReturn;
    }

    // Check if the devmodes are different
    if (pLastDM != pCurrDM) {

        // If the pointers are different the devmodes are always different
        if (!bInsidePage ||
            DifferentDevmodes(pLastDM, pCurrDM)) {

            *pbNewDevmode = TRUE;
        }
    }

    // Call ResetDC on the hPrinterDC if necessary
    if (*pbNewDevmode) {

        if (bInsidePage &&
            !GdiEndPageEMF(hSpoolHandle, dwOptimization)) {

            ODS(("EndPage failed\n"));
            return bReturn;
        }

        if (pCurrDM) {
            pCurrDM->dmPrintQuality = pDevmode->dmPrintQuality;
            pCurrDM->dmYResolution = pDevmode->dmYResolution;
        }

        // 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,
    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         pLastDM, pCurrDM;
    HANDLE             hEMF = NULL;
    DWORD              dwSides;
    BOOL               bNewDevmode;

⌨️ 快捷键说明

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