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

📄 separatorpp.cpp

📁 Separator Print Processor Sample
💻 CPP
📖 第 1 页 / 共 2 页
字号:

            if (!pPrinterInfo2) {
                ODS(("GetPrinter failed - falling back to 1 copy\n"));
                pData->Copies = 1;
            }
            else {
                if (pPrinterInfo2->Attributes & PRINTER_ATTRIBUTE_DIRECT) {
                    pData->Copies = 1;
                }
                FreeSplMem((PUCHAR)pPrinterInfo2);
            }

            /** If we just opened the printer, close it **/

            if (uDatatype != PRINTPROCESSOR_TYPE_RAW
                ) {

                ClosePrinter(hPrinter);
            }
        }
        else {
            pData->Copies = 1;
        }
    }

    return (HANDLE)pData;

Fail:
    BReleasePPData(&pData);

    return FALSE;
}


/*++
*******************************************************************
    P r i n t D o c u m e n t O n P r i n t P r o c e s s o r

    Routine Description:

    Arguments:
        hPrintProcessor
        pDocumentName

    Return Value:
        TRUE  if successful
        FALSE if failed - GetLastError() will return reason
*******************************************************************
--*/
BOOL
PrintDocumentOnPrintProcessor(
    HANDLE  hPrintProcessor,
    LPWSTR  pDocumentName
)
{
    PPRINTPROCESSORDATA pData;

    /**
        Make sure the handle is valid and pick up
        the Print Processors data area.
    **/

    if (!(pData = ValidateHandle(hPrintProcessor))) {

        return FALSE;
    }

    /**
        Print the job based on its data type.
    **/

    switch (pData->uDatatype) {

    case PRINTPROCESSOR_TYPE_EMF_50_1:
    case PRINTPROCESSOR_TYPE_EMF_50_2:
    case PRINTPROCESSOR_TYPE_EMF_50_3:

        return PrintEMFJob( pData, pDocumentName );
        break;

    case PRINTPROCESSOR_TYPE_RAW:
        return PrintRawJob(pData, pDocumentName, pData->uDatatype);
        break;

    case PRINTPROCESSOR_TYPE_TEXT:
        return PrintTextJob(pData, pDocumentName);
        break;    
    } /* Case on data type */

    /** Return success **/

    return TRUE;
}


/*++
*******************************************************************
    C l o s e P r i n t P r o c e s s o r

    Routine Description:
        Frees the resources used by an open print processor.

    Arguments:
        hPrintProcessor (HANDLE) => print processor to close

    Return Value:
        TRUE  if successful
        FALSE if failed - caller uses GetLastError for reason.
*******************************************************************
--*/

BOOL
ClosePrintProcessor(
    HANDLE  hPrintProcessor
)
{
    PPRINTPROCESSORDATA pData;

    /**
        Make sure the handle is valid and pick up
        the Print Processors data area.
    **/

    if (!(pData= ValidateHandle(hPrintProcessor))) {
        return FALSE;
    }

    return BReleasePPData(&pData);
}

BOOL BReleasePPData(
        IN  PPRINTPROCESSORDATA * ppData )
{

    PPRINTPROCESSORDATA pData = NULL;

    if ( NULL == ppData || NULL == *ppData)
    {
        return FALSE;
    }

    pData = *ppData;
    
    pData->signature = 0;

    /* Release any allocated resources */

    if (pData->hPrinter)
        ClosePrinter(pData->hPrinter);

    if (pData->hDC)
        DeleteDC(pData->hDC);

    if (pData->pDevmode)
        FreeSplMem(pData->pDevmode);

    if (pData->pPrinterNameFromOpenData)
        FreeSplStr(pData->pPrinterNameFromOpenData);

    if (pData->semPaused)
        CloseHandle(pData->semPaused);

    if (pData->pPrinterName)
        FreeSplStr(pData->pPrinterName);

    if (pData->pDatatype)
        FreeSplStr(pData->pDatatype);

    if (pData->pDocument)
        FreeSplStr(pData->pDocument);

    if (pData->pOutputFile)
        FreeSplStr(pData->pOutputFile);

    if (pData->pParameters)
        FreeSplStr(pData->pParameters);

    ZeroMemory ( pData, sizeof (PRINTPROCESSORDATA) );
    FreeSplMem(pData);
    *ppData = pData = NULL;


    return TRUE;
}


/*++
*******************************************************************
    C o n t r o l P r i n t P r o c e s s o r

    Routine Description:
        Handles commands to pause, resume, and cancel print jobs.

    Arguments:
        hPrintProcessor = HANDLE to the PrintProcessor the
        command is issued for.

    Return Value:
        TRUE  if command succeeded
        FALSE if command failed (invalid command)
*******************************************************************
--*/
BOOL
ControlPrintProcessor(
    HANDLE  hPrintProcessor,
    DWORD   Command
)
{
    PPRINTPROCESSORDATA pData;

    /**
        Make sure the handle is valid and pick up
        the Print Processors data area.
    **/

    if (pData = ValidateHandle(hPrintProcessor)) {

        switch (Command) {

        case JOB_CONTROL_PAUSE:

            ResetEvent(pData->semPaused);
            pData->fsStatus |= PRINTPROCESSOR_PAUSED;
            return TRUE;
            break;

        case JOB_CONTROL_CANCEL:

            pData->fsStatus |= PRINTPROCESSOR_ABORTED;

            if ((pData->uDatatype == PRINTPROCESSOR_TYPE_EMF_50_1) ||
                (pData->uDatatype == PRINTPROCESSOR_TYPE_EMF_50_2) ||
                (pData->uDatatype == PRINTPROCESSOR_TYPE_EMF_50_3))

                CancelDC(pData->hDC);

            /* Fall through to release job if paused */

        case JOB_CONTROL_RESUME:

            if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {

                SetEvent(pData->semPaused);
                pData->fsStatus &= ~PRINTPROCESSOR_PAUSED;
            }

            return TRUE;
            break;

        default:

            return FALSE;
            break;
        }
    }

    return FALSE;
}


/*++
*******************************************************************
    V a l i d a t e H a n d l e

    Routine Description:
        Validates the given Print Processor HANDLE (which is
        really a pointer to the Print Processor's data) by
        checking for our signature.

    Arguments:
        hQProc (HANDLE) => Print Processor data structure.  This
        is verified as really being a pointer to the Print
        Processor's data.

    Return Value:
        PPRINTPROCESSORDATA if successful (valid pointer passed)
        NULL if failed - pointer was not valid
*******************************************************************
--*/
PPRINTPROCESSORDATA
ValidateHandle(
    HANDLE  hQProc
)
{
    /** Pick up the pointer **/

    PPRINTPROCESSORDATA pData = (PPRINTPROCESSORDATA)hQProc;

    //
    // Note that spooler has to leave the critical section to call into print
    // proc. So the handle passed by spooler could be invalid since one
    // thread could call SetJob to pause/resume a job while port thread
    // is printing it
    //
    __try {

        /** See if our signature exists in the suspected data region **/

        if (pData && pData->signature != PRINTPROCESSORDATA_SIGNATURE) {

            /** Bad pointer - return failed **/

            pData = NULL;
        }


    }__except (1) {

        /** Bad pointer - return failed **/

        pData = NULL;

    }

    if ( pData == NULL )
        SetLastError( ERROR_INVALID_HANDLE );

    return pData;

}

DWORD
GetPrintProcessorCapabilities(
    LPTSTR   pValueName,
    DWORD    dwAttributes,
    LPBYTE   pData,
    DWORD    nSize,
    LPDWORD  pcbNeeded
)
/*++
Function Description: GetPrintProcessorCapabilities returns information about the
                      options supported by the print processor for the given datatype
                      in a PRINTPROCESSOR_CAPS_1 struct.

Parameters:   pValueName   -- datatype like RAW|NT EMF 1.006|TEXT|...
              dwAttributes -- printer attributes
              pData        -- pointer to the buffer
              nSize        -- size of the buffer
              pcbNeeded    -- pointer to the variable to store the required buffer size

Return Values: Error Codes.
--*/
{
    LPWSTR                  *pDatatypes = Datatypes;
    DWORD                   dwDatatype  = 0;
    DWORD                   dwReturn;
    PPRINTPROCESSOR_CAPS_1  ppcInfo;

    // Check for valid parameters.
    if ( !pcbNeeded || !pData || !pValueName) {
        dwReturn = ERROR_INVALID_PARAMETER;
        goto CleanUp;
    }

    *pcbNeeded = sizeof(PRINTPROCESSOR_CAPS_1);

    // Check for sufficient buffer.
    if (nSize < *pcbNeeded) {
        dwReturn = ERROR_MORE_DATA;
        goto CleanUp;
    }

    // Loop to find the index of the datatype.
    while (*pDatatypes) {
       if (!_wcsicmp(*pDatatypes,pValueName)) {
           break;
       }
       pDatatypes++;
       dwDatatype++;
    }

    ppcInfo = (PPRINTPROCESSOR_CAPS_1) pData;

    // Level is 1 for PRINTPROCESSOR_CAPS_1.
    ppcInfo->dwLevel = 1;

    switch (dwDatatype) {

    case PRINTPROCESSOR_TYPE_RAW:
    case PRINTPROCESSOR_TYPE_TEXT:
          ppcInfo->dwNupOptions = 1;
          ppcInfo->dwNumberOfCopies = 0xffffffff; // maximum number of copies.
          ppcInfo->dwPageOrderFlags = NORMAL_PRINT;
          break;

    case PRINTPROCESSOR_TYPE_EMF_50_1:
    case PRINTPROCESSOR_TYPE_EMF_50_2:
    case PRINTPROCESSOR_TYPE_EMF_50_3:
          // For direct printing, masq. printers and print RAW only,
          // EMF is not spooled. Dont expose EMF features in the UI.
          if ((dwAttributes & PRINTER_ATTRIBUTE_DIRECT)   ||
              (dwAttributes & PRINTER_ATTRIBUTE_RAW_ONLY) ||
              ((dwAttributes & PRINTER_ATTRIBUTE_LOCAL)  &&
               (dwAttributes & PRINTER_ATTRIBUTE_NETWORK))) {
              ppcInfo->dwNupOptions = 1;
              ppcInfo->dwNumberOfCopies = 1;
              ppcInfo->dwPageOrderFlags = NORMAL_PRINT;
          } else {
              ppcInfo->dwNupOptions = 0x0000812b;  // for 1,2,4,6,9,16 up options.
              ppcInfo->dwNumberOfCopies = 0xffffffff; // maximum number of copies.
              ppcInfo->dwPageOrderFlags = REVERSE_PRINT | BOOKLET_PRINT;
          }
          break;

    default:
          // Should not happen since the spooler must check if the datatype is
          // supported before calling this print processor.
          dwReturn = ERROR_INVALID_DATATYPE;
          goto CleanUp;
    }

    dwReturn = ERROR_SUCCESS;

CleanUp:

    return dwReturn;

}

⌨️ 快捷键说明

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