Share via


Vorgehensweise: Drucken mit der XPS-Druck-API

In diesem Thema wird beschrieben, wie Sie die XPS-Druck-API verwenden, um von einer Windows-Anwendung aus zu drucken.

Die XPS-Druck-API ermöglicht nativen Windows-Anwendungen das Drucken von XPS-Dokumenten. Eine Anwendung kann mithilfe der XPS-Dokument-API ein XPS-Dokument erstellen. Dies wird im Hilfethema Allgemeine XPS-Dokumentprogrammieraufgaben beschrieben. Sobald ein XPS-Dokument erstellt wurde, kann die Anwendung die XPS-Druck-API verwenden, um es zu drucken.

Die Verwendung der XPS-Druck-API zum Drucken eines Dokuments aus einer Anwendung umfasst die folgenden Schritte.

Die XPS-Druck-API erfordert zum Drucken ein XPS-Dokument. Im folgenden Beispiel wird das XPS-Dokument erstellt, während es von der XPS-Druck-API an den Drucker gesendet wird. Es ist auch möglich, ein XPS-Dokument zu erstellen, ohne es an einen Drucker zu senden, indem Sie die XPS-Dokument-API verwenden und es als XPS OM verwalten oder das XPS OM als XPS-Dokument speichern. Weitere Informationen zur Verwendung eines XPS-OM finden Sie in der XPS-Dokument-API.

Initialisieren der COM-Schnittstelle

Initialisieren Sie die COM-Schnittstelle, wenn die Anwendung dies noch nicht getan hat.

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

Erstellen eines Vervollständigungsereignisses

Erstellen Sie ein Vervollständigungsereignis, das die XPS-Druck-API verwendet, um die Anwendung zu benachrichtigen, wenn der Druckspooler das gesamte Dokument aus der Anwendung empfangen hat. Die XPS-Druck-API unterstützt auch ein Statusereignis, damit eine Anwendung über andere Spoolingaktivitäten informiert werden kann.

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

Starten eines XPS-Druckauftrags

Starten Sie einen XPS-Druckauftrag, indem Sie StartXpsPrintJob aufrufen. StartXpsPrintJob gibt einen Stream zurück, in den die Anwendung das zu druckende Dokument sendet.

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

Erstellen einer IXpsOMPackageWriter-Schnittstelle

Erstellen Sie eine IXpsOMPackageWriter-Schnittstelle , indem Sie IXpsOMObjectFactory::CreatePackageWriterOnStream für den von StartXpsPrintJob zurückgegebenen Stream aufrufen.

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

Starten Sie für jedes Dokument in diesem Druckauftrag ein neues Dokument, und fügen Sie diesem Dokument dann Seiten hinzu.

Starten eines neuen Dokuments

Starten Sie ein neues Dokument im Paketschreiber, indem Sie IXpsOMPackageWriter::StartNewDocument aufrufen. Wenn ein Dokument geöffnet ist, wenn diese Methode aufgerufen wird, wird es geschlossen und ein neues Dokument geöffnet.

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

Seite hinzufügen

Rufen Sie IXpsOMPackageWriter::AddPage auf, um alle Dokumentseiten aus der Anwendung in das neue Dokument im Paketschreiber zu schreiben.

Hinweis

Es wird davon ausgegangen, dass die Anwendung die Seite vor diesem Schritt erstellt hat. Weitere Informationen zum Erstellen von Dokumentseiten und zum Hinzufügen von Inhalten zu diesen finden Sie unter Allgemeine XPS-Dokumentprogrammierungsaufgaben.

 

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

Schließen der IXpsOMPackageWriter-Schnittstelle

Nachdem alle Dokumente für diesen Druckauftrag geschrieben wurden, rufen Sie IXpsOMPackageWriter::Close auf, um das Paket zu schließen.

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

Schließen des Druckauftragsstreams

Schließen Sie den Druckauftragsstream, indem Sie Close aufrufen, wodurch dem Druckspooler mitgeteilt wird, dass der gesamte Druckauftrag von der Anwendung gesendet wurde.

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

Warten auf das Vervollständigungsereignis

Warten Sie auf das Abschlussereignis des Druckauftrags.

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

Nachdem das Abschlussereignis signalisiert wurde, rufen Sie GetJobStatus auf, um den Auftrag status zu erhalten.

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

Freigeben von Ressourcen

Nachdem ein Auftrag status die Fertigstellung anzeigt, lassen Sie die für diesen Druckauftrag verwendeten Schnittstellen und Ressourcen frei.

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