Procedura: Stampa con l'API di stampa XPS
Questo argomento descrive come usare l'API di stampa XPS per stampare da un'applicazione Windows.
L'API di stampa XPS consente alle applicazioni Windows native di stampare documenti XPS. Un'applicazione può creare un documento XPS usando l'API Documento XPS. L'argomento Attività di programmazione documenti COMUNI XPS descrive come eseguire questa operazione. Dopo aver creato un documento XPS, l'applicazione può usare l'API di stampa XPS per stamparla.
L'uso dell'API di stampa XPS per stampare un documento da un'applicazione prevede la procedura seguente.
- Inizializzare l'interfaccia COM
- Creare un evento di completamento
- Avviare un processo di stampa XPS
- Creare un'interfaccia IXpsOMPackageWriter
- Chiudere l'interfaccia IXpsOMPackageWriter
- Chiudere il flusso di processi di stampa
- Attendere l'evento di completamento
- Rilasciare le risorse
L'API di stampa XPS richiede la stampa di un documento XPS. Nell'esempio seguente viene creato il documento XPS quando viene inviato alla stampante dall'API Di stampa XPS. È anche possibile creare un documento XPS senza inviarlo a una stampante usando l'API Documento XPS e mantenendola come XPS OM o salvando XPS OM come documento XPS. Per altre informazioni sull'uso di un OM XPS, vedere l'API documento XPS.
Inizializzare l'interfaccia COM
Inizializzare l'interfaccia COM, se l'applicazione non è già stata eseguita.
// 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;
}
Creare un evento di completamento
Creare un evento di completamento, che l'API di stampa XPS usa per notificare all'applicazione quando il spooler di stampa ha ricevuto l'intero documento dall'applicazione. L'API di stampa XPS supporta anche un evento di stato in modo che un'applicazione possa conoscere altre attività di spooling.
// 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);
}
Avviare un processo di stampa XPS
Avviare un processo di stampa XPS chiamando StartXpsPrintJob. StartXpsPrintJob restituisce un flusso in cui l'applicazione invierà il documento da stampare.
// 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);
}
Creare un'interfaccia IXpsOMPackageWriter
Creare un'interfaccia IXpsOMPackageWriter chiamando IXpsOMObjectFactory::CreatePackageWriterOnStream nel flusso restituito da 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;
}
Per ogni documento in questo processo di stampa, avviare un nuovo documento e quindi aggiungere pagine a tale documento.
Avviare un nuovo documento
Avviare un nuovo documento nel writer del pacchetto chiamando IXpsOMPackageWriter::StartNewDocument. Se un documento viene aperto quando viene chiamato questo metodo, viene chiuso e viene aperto un nuovo documento.
// 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;
}
Aggiungere una pagina
Chiamare IXpsOMPackageWriter::AddPage per scrivere ognuna delle pagine del documento dall'applicazione al nuovo documento nel writer del pacchetto.
Nota
Si presuppone che l'applicazione abbia creato la pagina prima di questo passaggio. Per altre informazioni sulla creazione di pagine dei documenti e sull'aggiunta di contenuto a loro, vedere Le attività comuni di programmazione dei documenti 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);
}
}
Chiudere l'interfaccia IXpsOMPackageWriter
Dopo aver scritto tutti i documenti per questo processo di stampa, chiamare IXpsOMPackageWriter::Close per chiudere il pacchetto.
if (SUCCEEDED(hr))
{
if (FAILED(hr = packageWriter->Close()))
{
fwprintf(
stderr,
L"ERROR: Could not close package writer: %08X\n",
hr);
}
}
Chiudere il flusso di processi di stampa
Chiudere il flusso del processo di stampa chiamando Close, che indica allo spooler di stampa che l'intero processo di stampa è stato inviato dall'applicazione.
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();
}
}
Attendere l'evento di completamento
Attendere l'evento di completamento del processo di stampa.
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);
}
}
Dopo aver segnalato l'evento di completamento, chiamare GetJobStatus per ottenere lo stato del processo.
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;
}
}
Rilasciare le risorse
Dopo il completamento di uno stato del processo, rilasciare le interfacce e le risorse usate per questo processo di stampa.
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;
}