Share via


방법: XPS 인쇄 API를 사용하여 인쇄

이 항목에서는 XPS 인쇄 API 를 사용하여 Windows 애플리케이션에서 인쇄하는 방법을 설명합니다.

XPS 인쇄 API를 사용하면 네이티브 Windows 애플리케이션에서 XPS 문서를 인쇄할 수 있습니다. 애플리케이션은 XPS 문서 API를 사용하여 XPS 문서를 만들 수 있습니다. 일반적인 XPS 문서 프로그래밍 작업 도움말 항목에서는 이 작업을 수행하는 방법을 설명합니다. XPS 문서가 만들어지면 애플리케이션은 XPS 인쇄 API를 사용하여 인쇄할 수 있습니다.

XPS 인쇄 API를 사용하여 애플리케이션에서 문서를 인쇄하려면 다음 단계가 포함됩니다.

XPS 인쇄 API를 사용하려면 XPS 문서를 인쇄해야 합니다. 다음 예제에서는 XPS 문서가 XPS 인쇄 API에 의해 프린터로 전송되면 만들어집니다. XPS 문서 API를 사용하고 XPS OM으로 유지 관리하거나 XPS OM을 XPS 문서로 저장하여 프린터로 보내지 않고 XPS 문서를 만들 수도 있습니다. XPS OM 사용에 대한 자세한 내용은 XPS 문서 API를 참조하세요.

COM 인터페이스 초기화

애플리케이션이 아직 수행하지 않은 경우 COM 인터페이스를 초기화합니다.

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

완료 이벤트 만들기

인쇄 스풀러가 애플리케이션에서 전체 문서를 받았을 때 XPS 인쇄 API 가 애플리케이션에 알리는 데 사용하는 완료 이벤트를 만듭니다. XPS Print API는 애플리케이션이 다른 스풀링 활동에 대해 알 수 있도록 진행률 이벤트도 지원합니다.

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

XPS 인쇄 작업 시작

StartXpsPrintJob을 호출하여 XPS 인쇄 작업을 시작합니다. StartXpsPrintJob 은 애플리케이션이 인쇄할 문서를 보낼 스트림을 반환합니다.

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

IXpsOMPackageWriter 인터페이스 만들기

StartXpsPrintJob에서 반환된 스트림에서 IXpsOMObjectFactory::CreatePackageWriterOnStream을 호출하여 IXpsOMPackageWriter 인터페이스를 만듭니다.

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

이 인쇄 작업의 각 문서에 대해 새 문서를 시작한 다음 해당 문서에 페이지를 추가합니다.

새 문서 시작

IXpsOMPackageWriter::StartNewDocument를 호출하여 패키지 작성기에서 새 문서를 시작합니다. 이 메서드를 호출할 때 문서가 열려 있으면 문서가 닫혀 있고 새 문서가 열립니다.

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

페이지 추가

IXpsOMPackageWriter::AddPage를 호출하여 애플리케이션의 각 문서 페이지를 패키지 작성기의 새 문서에 씁니다.

참고

애플리케이션은 이 단계 이전에 페이지를 만든 것으로 간주됩니다. 문서 페이지를 만들고 콘텐츠를 추가하는 방법에 대한 자세한 내용은 일반적인 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);
        }
    }

IXpsOMPackageWriter 인터페이스 닫기

이 인쇄 작업을 위해 모든 문서를 작성한 후 IXpsOMPackageWriter::Close 를 호출하여 패키지를 닫습니다.

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

인쇄 작업 스트림 닫기

닫기를 호출하여 인쇄 작업 스트림을 닫습니다. 이 경우 애플리케이션에서 전체 인쇄 작업이 전송되었음을 인쇄 스풀러에 알릴 수 있습니다.

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

완료 이벤트 대기

인쇄 작업의 완료 이벤트를 기다립니다.

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

완료 이벤트가 신호를 받은 후 GetJobStatus를 호출하여 작업 상태 가져옵니다.

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

리소스 해제

작업 상태 완료를 나타내면 이 인쇄 작업에 사용되는 인터페이스 및 리소스를 해제합니다.

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