Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе описывается использование API печати XPS для печати из приложения Windows.
API печати XPS позволяет собственным приложениям Windows печатать документы XPS. Приложение может создать документ XPS с помощью API документов XPSXPS. В разделе Общие задачи программирования документов XPS описано, как это сделать. После создания документа XPS приложение может использовать API печати XPS для печати.
Использование API печати XPS для печати документа из приложения включает следующие действия.
- Инициализация COM-интерфейса
- Создайте событие завершения
- Начните задание печати XPS
- Создание интерфейса IXpsOMPackageWriter
- Закройте интерфейс IXpsOMPackageWriter
- Закрыть поток заданий на печать
- Дождитесь события завершения
- освобождение ресурсов
Для API печати XPS требуется документ XPS для печати. В следующем примере документ XPS создается так, как он отправляется на принтер API печати XPS. Кроме того, можно создать документ XPS, не отправляя его на принтер, с помощью API документов XPS , поддерживая его как XPS OM или сохраняя XPS OM в виде документа XPS. Дополнительные сведения об использовании OM XPS см. в API документов XPS.
Инициализация 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 Print API для уведомления приложения о том, что диспетчер печати получил весь документ от приложения. API печати XPS также поддерживает событие хода выполнения, чтобы приложение знало о других действиях, связанных с «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);
}
Запуск задания печати XPS
Запустите задание печати XPS, вызвав StartXpsPrintJob. 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
Создайте интерфейс IXpsOMPackageWriter путем вызова IXpsOMObjectFactory::CreatePackageWriterOnStream в потоке, возвращенном 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;
}
Для каждого документа в этом задании печати запустите новый документ и добавьте страницы в этот документ.
Запуск нового документа
Начните новый документ в модуле записи пакета, вызвав 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);
}
}
Закрытие потока заданий печати
Закройте поток заданий печати, вызвав Close, что сообщает диспетчеру печати, что приложение отправило всё задание печати.
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;
}