How To: Drucken mit der XPS-Druck-API
In diesem Thema wird beschrieben, wie Sie die XPS-Druck-API zum Drucken aus einer Windows verwenden.
Mit der XPS-Druck-API können native Windows XPS-Dokumente drucken. Eine Anwendung kann ein XPS-Dokument mithilfe der XPS-Dokument-API erstellen. Im Hilfethema Allgemeine XPS-Dokumentprogrammieraufgaben wird beschrieben, wie dies funktioniert. Sobald ein XPS-Dokument erstellt wurde, kann die Anwendung es mithilfe der XPS-Druck-API drucken.
Die Verwendung der XPS-Druck-API zum Drucken eines Dokuments aus einer Anwendung umfasst die folgenden Schritte.
- Com-Schnittstelle initialisieren
- Erstellen eines Abschlussereignis
- Starten eines XPS-Druckauftrags
- Erstellen einer IXpsOMPackageWriter-Schnittstelle
- Schließen der IXpsOMPackageWriter-Schnittstelle
- Schließen des Druckauftragsstreams
- Warten auf das Abschlussereignis
- Freigeben von Ressourcen
Für die XPS-Druck-API ist ein XPS-Dokument zum Drucken erforderlich. 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 mithilfe der XPS-Dokument-API an einen Drucker zu senden und es als XPS OM zu verwalten oder das XPS OM als XPS-Dokument zu speichern. Weitere Informationen zur Verwendung eines XPS OM finden Sie in der XPS-Dokument-API.
Com-Schnittstelle initialisieren
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 Abschlussereignis
Erstellen Sie ein Abschlussereignis, das von der XPS-Druck-API verwendet wird, um die Anwendung zu benachrichtigen, wenn der Druckspooler das gesamte Dokument von der Anwendung empfangen hat. Die XPS-Druck-API unterstützt auch ein Statusereignis, damit eine Anwendung über andere Spoolingaktivitäten erfahren 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 stream aufrufen, der von StartXpsPrintJob zurückgegeben wird.
// 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 Paketwriter, 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;
}
Hinzufügen einer Seite
Rufen Sie IXpsOMPackageWriter::AddPage auf, um jede der Seiten des Dokuments aus der Anwendung in das neue Dokument im Paketwriter 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-Dokumentprogrammieraufgaben.
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 Schließenaufrufen, wodurch der Druckspooler darüber informiert 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 Abschlussereignis
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 Auftragsstatus 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 Auftragsstatus den Abschluss angezeigt hat, geben Sie die Schnittstellen und Ressourcen frei, die für diesen Druckauftrag verwendet werden.
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;
}