Stampare un file XPS OM
Viene descritto come inviare un file XPS OM a una stampante come documento XPS.
Per istruzioni su come stampare un file XPS OM contenente un documento XPS completo, vedere Stampare un XPS OM completo. Per contenere un documento XPS, un XPS OM deve includere gli elementi elencati in Create a Blank XPS OM.To contain an XPS document, an XPS OM must include the items listed in Create a Blank XPS OM.
Per istruzioni su come stampare un file XPS OM che viene creato o elaborato una pagina alla volta, vedere Stampa incrementale di un file XPS OM.
Prima di usare questi esempi di codice nel programma, leggere la dichiarazione di non responsabilità in Attività comuni di programmazione documenti XPS.
In questo argomento si apprenderà come eseguire le attività seguenti:
Stampare un file XPS OM completo
Quando un XPS OM contiene un documento XPS completo, il metodo WriteToStream dell'interfaccia IXpsOMPackage può inviare il contenuto di XPS OM a una stampante o a una coda di stampa.
Per rilevare quando il processo di stampa è stato completato, creare un handle di evento come illustrato nell'esempio seguente.
HANDLE completionEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (NULL == completionEvent)
{
hr = HRESULT_FROM_WIN32(GetLastError());
// The method can continue, but print spooling completion
// cannot be checked without a valid event handle.
}
Per stampare un file XPS OM completo:
- Creare un nuovo flusso di processi di stampa chiamando StartXpsPrintJob.
- Inviare il contenuto di XPS OM al flusso chiamando il metodo WriteToStream del pacchetto.
- Chiudere il flusso del processo di stampa chiamando il metodo Close del flusso.
- Attendere che il processo di stampa segnali che è stato completato.
- Controllare lo stato di completamento.
- Chiudere e rilasciare le risorse.
IXpsPrintJob *job = NULL;
IXpsPrintJobStream *jobStream = NULL;
hr = StartXpsPrintJob(
printerName,
NULL,
NULL,
NULL,
completionEvent,
NULL,
0,
&job,
&jobStream,
NULL);
// Write package to print job stream
hr = package->WriteToStream (jobStream, FALSE);
// Close the stream to tell the print job
// that the entire document has been sent.
hr = jobStream->Close();
// Wait for the print job to finish spooling...
if (NULL != completionEvent) {
if (WaitForSingleObject(completionEvent, INFINITE) == WAIT_OBJECT_0)
{
// Get the print job status to see why the wait completed.
// Note that without waiting for a completion event,
// the print job may not be complete when the status is queried.
XPS_JOB_STATUS jobStatus;
hr = job->GetJobStatus(&jobStatus);
// Evaluate the job status returned.
switch (jobStatus.completion)
{
case XPS_JOB_COMPLETED:
// The job completed as expected.
hr = S_OK;
break;
case XPS_JOB_CANCELLED:
// The job was canceled.
hr = E_FAIL;
break;
case XPS_JOB_FAILED:
// The job failed,
// jobStatus.jobStatus has the reason.
hr = E_FAIL;
break;
default:
// An unexpected value was returned.
hr = E_UNEXPECTED;
break;
}
// Release completion event handle
CloseHandle(completionEvent);
}
else
{ // there was a problem, set hr to error status
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
// hr contains the result of the print operation
CoUninitialize(); // if COM is no longer needed in this thread
Stampare in modo incrementale un file XPS OM
È possibile inviare in modo incrementale i componenti del documento di un MODULO XPS a un processo di stampa, creando un flusso di processo di stampa XPS e quindi passando i singoli componenti del documento al flusso del processo di stampa, uno alla volta. La sequenza in cui vengono inviati i componenti del documento determina la modalità di visualizzazione nel documento completato. Pertanto, prima che un programma possa chiamare il codice in questo esempio, deve organizzare correttamente i componenti del documento.
Prima di usare le interfacce XPS OM, inizializzare COM nel thread come illustrato nel codice di esempio seguente.
HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
Per monitorare il completamento del processo di stampa, creare un handle di evento come illustrato nel codice di esempio seguente.
HANDLE completionEvent = NULL;
completionEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (NULL == completionEvent)
{
hr = HRESULT_FROM_WIN32(GetLastError());
// The method can continue, but print spooling completion
// cannot be checked without a valid event handle.
}
Creare un nuovo flusso di processo di stampa e un nuovo writer di pacchetti. Passare ognuno dei componenti del documento ai metodi del writer di pacchetti corrispondenti nella stessa sequenza visualizzata nel documento completato.
Avviare ogni nuovo documento, quindi aggiungervi pagine. Dopo aver passato tutti i componenti del documento al flusso del processo di stampa, chiudere il flusso, attendere il completamento del processo di stampa e quindi chiudere e rilasciare le risorse aperte.
- Creare un nuovo flusso di processi di stampa chiamando StartXpsPrintJob.
- Creare un URI di parte per la parte FixedDocumentSequence.
- Creare un nuovo writer di pacchetti nel flusso del processo di stampa.
- Per ogni documento da scrivere:
- Creare un nuovo URI di parte per la parte FixedDocument.
- Avviare un nuovo documento nel writer di pacchetti.
- Per ogni pagina del documento corrente, creare un URI di parte per la parte FixedPage e aggiungere la pagina al writer di pacchetti.
- Dopo che tutte le pagine sono state aggiunte al writer di pacchetti, chiuderla.
- Chiudere il flusso del processo di stampa.
- Attendere il completamento del processo di stampa.
- Controllare lo stato di completamento.
- Chiudere e rilasciare risorse aperte.
IXpsPrintJob* job = NULL;
IXpsPrintJobStream* jobStream = NULL;
hr = StartXpsPrintJob(
argv[1],
NULL,
NULL,
NULL,
completionEvent,
NULL,
0,
&job,
&jobStream,
NULL);
// Note the implicit requirement that CoInitializeEx
// has previously been called from this thread.
IXpsOMObjectFactory *xpsFactory = NULL;
hr = CoCreateInstance(
__uuidof(XpsOMObjectFactory),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IXpsOMObjectFactory),
reinterpret_cast<void**>(&xpsFactory)
);
// Create part URI for FixedDocumentSequence part
// This can use a static string because there is only one
// FixedDocumentSequence part in the print job.
IOpcPartUri *partUri = NULL;
hr = xpsFactory->CreatePartUri(L"/FixedDocumentSequence.fdseq", &partUri);
// Create the package writer on the print job stream
// Note that the interleaving parameter set to
// XPS_INTERLEAVING_ON, the package writer will create
// empty print ticket parts when a NULL pointer is
// passed in the print ticket argument of this method,
// the StartNewDocument method, and the AddPage method.
// For more information, see the help for these methods.
IXpsOMPackageWriter *packageWriter = NULL;
hr = xpsFactory->CreatePackageWriterOnStream(
jobStream,
TRUE,
XPS_INTERLEAVING_ON, // to create blank print ticket objects
partUri,
NULL,
NULL,
NULL,
NULL,
&packageWriter);
// release partUri after it's been used to create new doc. seq.
if (partUri)
{
partUri->Release();
partUri = NULL;
}
// Add document content to the print job stream.
int docNumber = 1;
int docsInPackage = 1; // Change this value as required.
while (docNumber <= docsInPackage) {
// Create a unique part URI for the current document.
WCHAR DocPartUri[MAX_PATH];
hr = MakeDocumentPartUri (docNumber, MAX_PATH, DocPartUri);
hr = xpsFactory->CreatePartUri(DocPartUri, &partUri);
// Initialize the new document in the package writer.
hr = packageWriter->StartNewDocument(partUri, NULL, NULL, NULL, NULL);
// release part URI after it's been used to create new doc.
if (partUri)
{
partUri->Release();
partUri = NULL;
}
// Add the pages
int pageNumber = 1;
int pagesInDocument = 1; // Change this value as required.
while (pageNumber <= pagesInDocument) {
// Create a unique part URI for the current page
WCHAR PagePartUri[MAX_PATH];
hr = MakePagePartUri (
docNumber,
pageNumber,
MAX_PATH,
PagePartUri);
hr = xpsFactory->CreatePartUri(PagePartUri, &partUri);
// create page in OM
XPS_SIZE pageSize = {816, 1056};
IXpsOMPage *xpsPage = NULL;
hr = xpsFactory->CreatePage(
&pageSize,
L"en-US",
partUri,
&xpsPage);
// release pagePartUri after it's been used to create the page
if (partUri)
{
partUri->Release();
partUri = NULL;
}
// add content to the page or retrieve
// the page from the XPS OM.
// (not shown in this example)
// add page to document
hr = packageWriter->AddPage(
xpsPage,
&pageSize,
NULL,
NULL,
NULL,
NULL);
if (xpsPage)
{
xpsPage->Release();
xpsPage = NULL;
}
// go to the next page
pageNumber++;
}
// the fixed document does not need to be closed.
// it will be closed when a new fixed doc is opened
// or the package is closed.
// go to the next document
docNumber++;
}
// Close the package writer when finished
hr = packageWriter->Close();
if (SUCCEEDED(hr))
{
// Close the print stream to tell the print
// job that the all document contents have
// been sent
hr = jobStream->Close();
// Wait for the print job to finish spooling...
if (NULL != completionEvent) {
if (WaitForSingleObject(completionEvent, INFINITE) == WAIT_OBJECT_0)
{
// Get the print job status to see why the wait completed.
// Note that without waiting for a completion event,
// the print job may not be complete when the status is queried.
XPS_JOB_STATUS jobStatus;
hr = job->GetJobStatus(&jobStatus);
// Evaluate the job status returned.
switch (jobStatus.completion)
{
case XPS_JOB_COMPLETED:
// The job completed as expected.
hr = S_OK;
break;
case XPS_JOB_CANCELLED:
// The job was canceled.
hr = E_FAIL;
break;
case XPS_JOB_FAILED:
// The job failed,
// jobStatus.jobStatus has the reason.
hr = E_FAIL;
break;
default:
// An unexpected value was returned.
hr = E_UNEXPECTED;
break;
}
// Release completion event handle
CloseHandle(completionEvent);
}
else
{ // there was a problem, set hr to error status
hr = HRESULT_FROM_WIN32(GetLastError());
}
}
}
else
{
// cancel the job, if one exists, because
// the close call returned an error
if (job) job->Cancel();
}
// hr contains the result of the print operation
// free/release pointers and handles used.
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;
}
CoUninitialize(); // If done with COM in this thread.
Quando il programma scrive i componenti del documento in modo incrementale, come illustrato in questo esempio, deve generare i nomi delle parti per ogni parte del documento inviata al flusso di processo di stampa. Nell'esempio precedente l'URI della parte FixedDocumentSequence viene creato da una stringa statica perché nel documento XPS è presente una sola parte di questo tipo. L'URI di ogni parte FixedPage e FixedDocument deve essere univoco all'interno del documento XPS. La compilazione dell'URI della parte usando l'indice di questi componenti consente di garantire che la stringa URI risultante sia univoca all'interno del documento XPS.
HRESULT MakeDocumentPartUri (
__in int docNumber,
__in DWORD partUriStringLength,
__inout LPWSTR partUriStringBuffer
)
{
// create a Part URI string using the document number
// that was passed as an argument
// for example, "/Documents/1/FixedDocument.fdoc"
// where "1" specifies the document number, which would
// change with each document printed
return S_OK;
}
HRESULT MakePagePartUri (
__in int docNumber,
__in int pageNumber,
__in DWORD partUriStringLength,
__inout LPWSTR partUriStringBuffer
)
{
// create a Part URI string using the document number
// and page number that were passed as an argument
// for example: "/Documents/1/Pages/1.fpage"
// where the first "1" between Documents and Pages
// specifies the document number, which would change with
// each document. The second "1" specifies the page number,
// which would change with each page in the document.
return S_OK;
}
Per altre informazioni sulla struttura di un documento XPS, vedere La specifica xml paper.
Argomenti correlati
-
Passaggi successivi
-
Usato in questa sezione
-
Ulteriori informazioni