213 lines
5.9 KiB
C++
213 lines
5.9 KiB
C++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
/*++
|
|
Routine Name:
|
|
CreatePrintTicketJobSimple
|
|
|
|
Routine Description:
|
|
|
|
A simple job for the printer "Microsoft XPS Document Writer" is created.
|
|
A print ticket is sent as part of this job using ExtEscape. The driver should understand
|
|
this escape, so we test whether driver is XPS capable before sending the Print Ticket.
|
|
A simple line of text is also sent.
|
|
|
|
Arguments:
|
|
|
|
<None>
|
|
|
|
Return Value:
|
|
|
|
S_OK if successful,
|
|
E_* if there is an error
|
|
|
|
--*/
|
|
|
|
HRESULT
|
|
CreatePrintTicketJobSimple(
|
|
VOID
|
|
)
|
|
{
|
|
HDC hdcMXDW = NULL;
|
|
HRESULT hr = S_OK;
|
|
PBYTE pEscData = NULL;
|
|
DWORD cbEscData = 0;
|
|
IStream *pPTStream = NULL;
|
|
PBYTE pbPTBuf = NULL;
|
|
DWORD cbPTBuf = 0;
|
|
PTPC_STATE_INFO si = {0};
|
|
|
|
BOOL bStartPageSent = FALSE;
|
|
BOOL bStartDocSent = FALSE;
|
|
|
|
|
|
// Copy printer name on the state info structure.
|
|
hr = StringCchCopy(si.szPrinterName, CCHOF(si.szPrinterName), gszPrinterName);
|
|
|
|
// Prepare Print Ticket Informaion that is to be sent.
|
|
// Get the Job Level User Print Ticket
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
hr = GetUserPrintTicketStream(&si, &pPTStream);
|
|
}
|
|
|
|
// The MXDW driver escape expects print ticket as a collection of bytes.
|
|
// The .xps package specification expects the PrintTicket to be encoded in the proper
|
|
// utf format. The best way to generate such a collection of utf encoded characters
|
|
// is to convert the PT stream directly into a buffer. The alternative of converting
|
|
// the stream to DOM and then converting DOM to BSTR(by calling DOMDocument->get_xml()
|
|
// is not only expensive, but also it may not generate the proper format for .xps package.
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
hr = ConvertPTStreamToBuffer(pPTStream,
|
|
&pbPTBuf,
|
|
&cbPTBuf
|
|
);
|
|
}
|
|
|
|
// Create Print Ticket Escape for sending to Printer
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
hr = PutTogetherEscapeStructureForPrintTicket(
|
|
MXDCOP_PRINTTICKET_FIXED_DOC,
|
|
pbPTBuf,
|
|
cbPTBuf,
|
|
&pEscData,
|
|
&cbEscData);
|
|
}
|
|
|
|
//
|
|
// Make sure the printer is installed and we can create its DC.
|
|
//
|
|
if (SUCCEEDED (hr) )
|
|
{
|
|
hdcMXDW = CreateDC( NULL, si.szPrinterName, NULL, NULL);
|
|
if(NULL == hdcMXDW)
|
|
{
|
|
DWORD dwLastError = GetLastError();
|
|
vFormatAndPrint(IDS_APP_CREATEDC_FAILED);
|
|
if ( ERROR_INVALID_PRINTER_NAME == dwLastError )
|
|
{
|
|
vFormatAndPrint(IDS_APP_MXDWPRINTER_NOTINSTALLED);
|
|
}
|
|
hr = HRESULT_FROM_WIN32(dwLastError);
|
|
}
|
|
}
|
|
|
|
|
|
// Make sure driver is a XPSDrv driver. i.e. it can accept XPS content.
|
|
if (SUCCEEDED (hr) )
|
|
{
|
|
hr = IsXPSCapableDriver(hdcMXDW);
|
|
|
|
// Only a return value of S_OK from IsXPSCapableDriver() means driver is XPS capable
|
|
// while we were querying the driver.
|
|
// A return value of S_FALSE means driver is not XPS capable
|
|
if ( S_FALSE == hr )
|
|
{
|
|
vFormatAndPrint(IDS_APP_XPS_CAPABLE_PRINTER_NOTINSTALLED);
|
|
hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
|
}
|
|
}
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
DOCINFO DocInfo = {
|
|
sizeof(DOCINFO),
|
|
L"Document with Single PrintTicket", // Title of the print job
|
|
NULL, // Not specifying output file. Driver will throw UI.
|
|
NULL, // Not specifying data type.
|
|
0
|
|
};
|
|
|
|
if( StartDoc(hdcMXDW, &DocInfo) > 0)
|
|
{
|
|
bStartDocSent = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Sometimes StartDoc fails if the specified output file cannot be opened.
|
|
// Sometimes that happens when a viewer is viewing the file, while the driver
|
|
// is trying to write to it.
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
if( StartPage(hdcMXDW) > 0)
|
|
{
|
|
bStartPageSent = TRUE;
|
|
}
|
|
else
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
// Send Print Ticket for the above page
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
if( ExtEscape(hdcMXDW, MXDC_ESCAPE, cbEscData, (LPCSTR) pEscData, 0, NULL) <= 0 )
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
// Send some text
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
WCHAR szText[] = L"This page is associated with default Print Ticket";
|
|
if ( FALSE == TextOut(hdcMXDW, 200, 200, szText, (int)wcslen(szText)) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
if (bStartPageSent)
|
|
{
|
|
EndPage(hdcMXDW);
|
|
}
|
|
|
|
if ( bStartDocSent)
|
|
{
|
|
EndDoc(hdcMXDW);
|
|
}
|
|
|
|
if(hdcMXDW != NULL)
|
|
{
|
|
DeleteDC(hdcMXDW);
|
|
hdcMXDW = NULL;
|
|
}
|
|
|
|
// Clean up
|
|
|
|
CoTaskMemFree(pbPTBuf);
|
|
pbPTBuf = NULL;
|
|
|
|
if(pEscData != NULL)
|
|
{
|
|
MemFree (pEscData);
|
|
pEscData = NULL;
|
|
}
|
|
|
|
if ( NULL != pPTStream )
|
|
{
|
|
pPTStream->Release();
|
|
pPTStream = NULL;
|
|
}
|
|
|
|
|
|
RelaseStateInfoContents(&si);
|
|
return hr;
|
|
}
|