Udostępnij przez


Instrukcje: drukowanie przy użyciu interfejsu API drukowania XPS

W tym temacie opisano, jak używać interfejsu API drukowania XPS do drukowania z aplikacji systemu Windows.

Interfejs API drukowania XPS umożliwia natywnym aplikacjom systemu Windows drukowanie dokumentów XPS. Aplikacja może utworzyć dokument XPS przy użyciu interfejsu API dokumentów XPS . Temat pomocy „Typowe zadania programistyczne dokumentów XPS” opisuje, jak to zrobić. Po utworzeniu dokumentu XPS aplikacja może wydrukować go przy użyciu interfejsu API drukowania XPS.

Użycie interfejsu API drukowania XPS do drukowania dokumentu z aplikacji obejmuje następujące kroki.

Interfejs API XPS wymaga dokumentu XPS do drukowania. W poniższym przykładzie dokument XPS jest tworzony i wysyłany do drukarki przez interfejs API drukowania XPS. Istnieje również możliwość utworzenia dokumentu XPS bez wysyłania go do drukarki przy użyciu API dokumentu XPS i utrzymywania go jako XPS OM lub przez zapisanie XPS OM jako dokumentu XPS. Aby uzyskać więcej informacji na temat korzystania z pakietu XPS OM, zobacz interfejs API dokumentów XPS.

Inicjowanie interfejsu COM

Zainicjuj interfejs COM, jeśli aplikacja jeszcze tego nie zrobiła.

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

Utwórz zdarzenie ukończenia

Utwórz zdarzenie zakończenia, którego API XPS do drukowania używa do powiadamiania aplikacji, gdy bufor wydruku otrzymał całkowity dokument z aplikacji. Interfejs API drukowania XPS obsługuje również zdarzenie postępu, dzięki czemu aplikacja może wiedzieć o innych procesach buforowania.

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

Uruchamianie zadania drukowania XPS

Uruchom zadanie drukowania XPS, wywołując StartXpsPrintJob. StartXpsPrintJob zwraca strumień, do którego aplikacja wyśle dokument do wydrukowania.

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

Tworzenie interfejsu IXpsOMPackageWriter

Utwórz interfejs IXpsOMPackageWriter, wywołując IXpsOMObjectFactory::CreatePackageWriterOnStream na strumieniu zwróconym przez 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;
    }

Dla każdego dokumentu w tym zadaniu drukowania uruchom nowy dokument, a następnie dodaj strony do tego dokumentu.

Rozpoczynanie nowego dokumentu

Rozpocznij nowy dokument w pisarce pakietów, wywołując IXpsOMPackageWriter::StartNewDocument. Jeśli dokument jest otwarty po wywołaniu tej metody, zostanie zamknięty i zostanie otwarty nowy dokument.

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

Dodawanie strony

Wywołaj IXpsOMPackageWriter::AddPage, aby zapisać każdą stronę dokumentu z aplikacji do nowego dokumentu w twórcy pakietów.

Notatka

Zakłada się, że aplikacja utworzyła stronę przed tym krokiem. Aby uzyskać więcej informacji na temat tworzenia stron dokumentów i dodawania do nich zawartości, zobacz Typowe zadania programowania dokumentów XPS.

 

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

Zamknij interfejs IXpsOMPackageWriter

Po napisaniu wszystkich dokumentów dla tego zadania drukowania wywołaj IXpsOMPackageWriter::Close, aby zamknąć pakiet.

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

Zamykanie strumienia zadań drukowania

Zamknij strumień zadania drukowania, wywołując Zamknij, który informuje bufor wydruku o tym, że całe zadanie drukowania zostało wysłane przez aplikację.

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

Poczekaj na wydarzenie ukończenia

Poczekaj na zdarzenie ukończenia zadania drukowania.

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

Po zasygnalizacji zdarzenia ukończenia wywołaj GetJobStatus, aby uzyskać stan zadania.

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

Zasoby wydania

Gdy stan zadania wskazuje ukończenie, zwolnij interfejsy i zasoby używane dla tego zadania drukowania.

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