Delen via


Procedure: Afdrukken met de XPS Print-API

In dit onderwerp wordt beschreven hoe u de XPS Print-API gebruikt om af te drukken vanuit een Windows-toepassing.

De XPS Print-API stelt systeemeigen Windows-toepassingen in staat XPS-documenten af te drukken. Een toepassing kan een XPS-document maken met behulp van de XPS-document-API. In het help-onderwerp Algemene programmeertaken voor XPS-documenten wordt beschreven hoe u dit doet. Zodra een XPS-document is gemaakt, kan de toepassing de XPS Print-API gebruiken om het af te drukken.

Het gebruik van de XPS Print-API om een document uit een toepassing af te drukken, omvat de volgende stappen.

Voor de XPS Print-API moet een XPS-document worden afgedrukt. In het volgende voorbeeld wordt het XPS-document gemaakt terwijl het door de XPS Print-API naar de printer wordt verzonden. Het is ook mogelijk om een XPS-document te maken zonder het naar een printer te verzenden met behulp van de XPS-document-API en te onderhouden als XPS OM of door het XPS OM op te slaan als een XPS-document. Zie de XPS Document-API voor meer informatie over het gebruik van een XPS OM.

COM-interface initialiseren

Initialiseer de COM-interface als de toepassing dit nog niet heeft gedaan.

    // Initialize the COM interface, if the application has not 
    //  already done so.
    if (FAILED(hr = CoInitializeEx(0, COINIT_MULTITHREADED)))
    {
        fwprintf(stderr, 
            L"ERROR: CoInitializeEx failed with HRESULT 0x%X\n", hr);
        return 1;
    }

Een voltooiingsevenement maken

Maak een voltooiingsgebeurtenis die de XPS Print-API gebruikt om de toepassing op de hoogte te stellen wanneer de afdrukspooler het hele document van de toepassing heeft ontvangen. De XPS Print-API ondersteunt ook een voortgangsgebeurtenis, zodat een toepassing op de hoogte blijft van andere spoolactiviteiten.

        // Create the completion event
        completionEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (!completionEvent)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            fwprintf(stderr, 
                L"ERROR: Could not create completion event: %08X\n", hr);
        }

Een XPS-afdruktaak starten

Start een XPS-afdruktaak door StartXpsPrintJobaan te roepen. StartXpsPrintJob retourneert een stroom waarin de toepassing het document verzendt dat moet worden afgedrukt.

        // Start an XPS Print Job
        if (FAILED(hr = StartXpsPrintJob(
                    printerName,
                    NULL,
                    NULL,
                    NULL,
                    completionEvent,
                    NULL,
                    0,
                    &job,
                    &jobStream,
                    NULL
                    )))
        {
            fwprintf(stderr, 
                L"ERROR: Could not start XPS print job: %08X\n", hr);
        }

Een IXpsOMPackageWriter-interface maken

Maak een IXpsOMPackageWriter interface door IXpsOMObjectFactory::CreatePackageWriterOnStream aan te roepen op de stream die wordt geretourneerd door StartXpsPrintJob.

    // Create an XPS OM Object Factory. If one has already been 
    //  created by the application, a new one is not necessary.
    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = CoCreateInstance(
                __uuidof(XpsOMObjectFactory), 
                NULL,
                CLSCTX_INPROC_SERVER, 
                IID_PPV_ARGS(&xpsFactory))))
        {
            fwprintf(
                stderr, 
                L"ERROR: Could not create XPS OM Object Factory: %08X\n", 
                hr);
        }
    }
    // Create the Part URI for the Fixed Document Sequence. The
    //  Fixed Document Sequence is the top-level element in the
    //  package hierarchy of objects. There is one Fixed Document
    //  Sequence in an XPS document.
    //
    // The part name is not specified by the XML Paper Specification,
    //  however, the name used in this example is the part name
    //  used by convention.
    //
    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = xpsFactory->CreatePartUri(
                    L"/FixedDocumentSequence.fdseq", 
                    &partUri)))
        {
            fwprintf(stderr, 
                L"ERROR: Could not create part URI: %08X\n", hr);
        }
    }

    // Create the package writer on the print job stream.
    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = xpsFactory->CreatePackageWriterOnStream(
                    jobStream,
                    TRUE,
                    XPS_INTERLEAVING_ON,
                    partUri,
                    NULL,
                    NULL,
                    NULL,
                    NULL,
                    &packageWriter
                    )
                )
           )
        {
            fwprintf(
                stderr, 
                L"ERROR: Could not create package writer: 0x%X\n", 
                hr);
        }
    }

    // Release the part URI interface.
    if (partUri)
    {
        partUri->Release();
        partUri = NULL;
    }

Start voor elk document in deze afdruktaak een nieuw document en voeg vervolgens pagina's toe aan dat document.

Een nieuw document starten

Start een nieuw document in de pakketschrijver door IXpsOMPackageWriter::StartNewDocumentaan te roepen. Als een document is geopend wanneer deze methode wordt aangeroepen, wordt het gesloten en wordt er een nieuw document geopend.

    // Create the Part URI for the Fixed Document. The
    //  Fixed Document part contains the pages of the document. 
    //  There can be one or more Fixed Documents in an XPS document.
    //
    // The part name is not specified by the XML Paper Specification,
    //  however, the name format used in this example is the format 
    //  used by convention. The number "1" in this example must be 
    //  changed for each document in the package. For example, 1 
    //  for the first document, 2 for the second, and so on.
    //

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = xpsFactory->CreatePartUri(
                    L"/Documents/1/FixedDocument.fdoc", 
                    &partUri)))
        {
            fwprintf(
                stderr, 
                L"ERROR: Could not create part URI: %08X\n", 
                hr);
        }
    }

    // Start the new document.
    //
    //  If there was already a document started in this page,
    //  this call will close it and start a new one.
    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = packageWriter->StartNewDocument(
                    partUri, 
                    NULL, 
                    NULL, 
                    NULL,
                    NULL)))
        {
            fwprintf(
                stderr, 
                L"ERROR: Could not start new document: 0x%X\n", 
                hr);
        }
    }
    
    // Release the part URI interface
    if (partUri)
    {
        partUri->Release();
        partUri = NULL;
    }

Een pagina toevoegen

Roep IXpsOMPackageWriter::AddPage aan om elk van de pagina's van het document van de toepassing naar het nieuwe document in de pakketschrijver te schrijven.

Notitie

De toepassing wordt ervan uitgegaan dat de pagina vóór deze stap is gemaakt. Zie de Algemene XPS-documentprogrammeertakenvoor meer informatie over het maken van documentpagina's en het toevoegen van inhoud.

 

    if (SUCCEEDED(hr))
    {
        // Add the current page to the document.
        if (FAILED(hr = packageWriter->AddPage(
                    xpsPage,
                    &pageSize,
                    NULL,
                    NULL,
                    NULL,
                    NULL
                    )))
        {
            fwprintf(
                stderr, 
                L"ERROR: Could not add page to document: %08X\n", 
                hr);
        }
    }

De interface IXpsOMPackageWriter sluiten

Nadat alle documenten zijn geschreven voor deze afdruktaak, roep aan IXpsOMPackageWriter::Close om het pakket te sluiten.

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = packageWriter->Close()))
        {
            fwprintf(
                stderr, 
                L"ERROR: Could not close package writer: %08X\n", 
                hr);
        }
    }

De afdruktaakstroom sluiten

Sluit de afdruktaakstroom door Sluitenaan te roepen, zodat de afdrukspooler aangeeft dat de hele afdruktaak door de toepassing is verzonden.

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = jobStream->Close()))
        {
            fwprintf(
                stderr,
                L"ERROR: Could not close job stream: %08X\n",
                hr);
        }
    }
    else
    {
        // Only cancel the job if we succeeded in creating a job.
        if (job)
        {
            // Tell the XPS Print API that we're giving up.  
            //  Don't overwrite hr with the return from this function.
            job->Cancel();
        }
    }

Wachten op het voltooiingsevenement

Wacht op de voltooiing van de afdruktaak.

    if (SUCCEEDED(hr))
    {
        wprintf(L"Waiting for job completion...\n");

        if (WaitForSingleObject(completionEvent, INFINITE) != 
                                                    WAIT_OBJECT_0)
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
            fwprintf(
                stderr, 
                L"ERROR: Wait for completion event failed: %08X\n", 
                hr);
        }
    }

Nadat de voltooiingsgebeurtenis is gesignaleerd, roept u GetJobStatus aan om de taakstatus op te halen.

    if (SUCCEEDED(hr))
    {
        if (FAILED(hr = job->GetJobStatus(&jobStatus)))
        {
            fwprintf(
                stderr, 
                L"ERROR: Could not get job status: %08X\n", 
                hr);
        }
    }

    if (SUCCEEDED(hr))
    {
        switch (jobStatus.completion)
        {
            case XPS_JOB_COMPLETED:
                break;
            case XPS_JOB_CANCELLED:
                fwprintf(stderr, L"ERROR: job was cancelled\n");
                hr = E_FAIL;
                break;
            case XPS_JOB_FAILED:
                fwprintf(
                    stderr, 
                    L"ERROR: Print job failed: %08X\n", 
                    jobStatus.jobStatus);
                hr = E_FAIL;
                break;
            default:
                fwprintf(stderr, L"ERROR: unexpected failure\n");
                hr = E_UNEXPECTED;
                break;
        }
    }

Resources vrijgeven

Nadat een taakstatus aangeeft dat de taak is voltooid, laat u de interfaces en resources los die voor deze afdruktaak worden gebruikt.

    if (packageWriter)
    {
        packageWriter->Release();
        packageWriter = NULL;
    }

    if (partUri)
    {
        partUri->Release();
        partUri = NULL;
    }

    if (xpsFactory)
    {
        xpsFactory->Release();
        xpsFactory = NULL;
    }

    if (jobStream)
    {
        jobStream->Release();
        jobStream = NULL;
    }

    if (job)
    {
        job->Release();
        job = NULL;
    }

    if (completionEvent)
    {
        CloseHandle(completionEvent);
        completionEvent = NULL;
    }