How to print custom headers and footers for a WebBrowser control in Internet Explorer (267240)
The information in this article applies to:
- Microsoft Internet Explorer (Programming) 4.0
- Microsoft Internet Explorer (Programming) 4.01
- Microsoft Internet Explorer (Programming) 5
- Microsoft Internet Explorer (Programming) 5.01
- Microsoft Internet Explorer (Programming) 5.5
- Microsoft Internet Explorer (Programming) 6.0
This article was previously published under Q267240 INTRODUCTION When you host the WebBrowser control, you may often need to override the default headers and
footers for a printed HTML document. Although Microsoft Internet Explorer 5.5
supports the configuration of printer templates, which allow you to customize
headers and footers, Internet Explorer version 4.0 and later versions support
the use of the IWebBrowser2::ExecWB method to customize headers and footers. MORE INFORMATIONIWebBrowser2::ExecWB is a wrapper for the Exec method of the IOleCommandTarget interface. The ExecWB method has the following signature:
HRESULT ExecWB(
OLECMDID cmdID,
OLECMDEXECOPT cmdexecopt,
VARIANT *pvaIn,
VARIANT *pvaOut
);
When you use an OLECMDID enumeration of the OLECMDID_PRINT element together with the
ExecWB method, you can specify extended printing information by passing in the
SAFEARRAY structure through the VARIANT argument pvaIn. This SAFEARRAY data
type takes a maximum of five items:
- A string (BSTR) that contains a custom header.
- A string (BSTR) that contains a custom footer.
- An IStream object that contains an HTML file that serves as an "optional
header." This is the e-mail header that you see in Microsoft Outlook and
Microsoft Outlook Express e-mail messages when you print them. This IStream object must point to a full, valid HTML document, not to HTML
fragments, or it will print incorrectly.
- An alternative URL to use for the document. This is only
relevant to Outlook and to Outlook Express.
- A set of printing flags (dwFlags) to configure the printer.
This is only relevant to Outlook and to Outlook Express.
The following Microsoft Visual C++ code shows an event handler
for a Print menu command in a Visual C++ WebBrowser host. The code focuses on
very simple header, footer, and optional header values.
LRESULT CWebOCWindow::OnPrint(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) {
SAFEARRAYBOUND psabBounds[1];
SAFEARRAY *psaHeadFoot;
HRESULT hr = S_OK;
// Variables needed to send IStream header to print operation.
HGLOBAL hG = 0;
IStream *pStream= NULL;
IUnknown *pUnk = NULL;
ULONG lWrote = 0;
LPSTR sMem = NULL;
if (!webOC) {
ATLTRACE(_T("DoPrint: Cannot print - WebBrowser control not ready\n"));
goto cleanup;
}
// Initialize header and footer parameters to send to ExecWB().
psabBounds[0].lLbound = 0;
psabBounds[0].cElements = 3;
psaHeadFoot = SafeArrayCreate(VT_VARIANT, 1, psabBounds);
if (NULL == psaHeadFoot) {
// Error handling goes here.
goto cleanup;
}
VARIANT vHeadStr, vFootStr, vHeadTxtStream;
long rgIndices;
VariantInit(&vHeadStr);
VariantInit(&vFootStr);
VariantInit(&vHeadTxtStream);
// Argument 1: Header
vHeadStr.vt = VT_BSTR;
vHeadStr.bstrVal = SysAllocString(L"This is my header string.");
if (vHeadStr.bstrVal == NULL) {
goto cleanup;
}
// Argument 2: Footer
vFootStr.vt = VT_BSTR;
vFootStr.bstrVal = SysAllocString(L"This is my footer string.");
if (vFootStr.bstrVal == NULL) {
ATLTRACE(_T("DoPrint: Could not allocate memory in %s: Line %d\n"), __FILE__, __LINE__);
goto cleanup;
}
// Argument 3: IStream containing header text. Outlook and Outlook
// Express use this to print out the mail header.
if ((sMem = (LPSTR)CoTaskMemAlloc(512)) == NULL) {
ATLTRACE(_T("DoPrint: Could not allocate memory in %s: Line %d\n"), __FILE__, __LINE__);
goto cleanup;
}
// We must pass in a full HTML file here, otherwise this
// becomes corrupted when we print.
sprintf(sMem, "<html><body><strong>Printed By:</strong> Custom WebBrowser Host 1.0<p></body></html>\0");
// Allocate an IStream for the LPSTR that we just created.
hG = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, strlen(sMem));
if (hG == NULL) {
ATLTRACE(_T("DoPrint: Could not allocate memory in %s: Line %d\n"), __FILE__, __LINE__);
goto cleanup;
}
hr = CreateStreamOnHGlobal(hG, TRUE, &pStream);
if (FAILED(hr)) {
ATLTRACE(_T("OnPrint::Failed to create stream from HGlobal: %lX\n"), hr);
goto cleanup;
}
hr = pStream->Write(sMem, strlen(sMem), &lWrote);
if (SUCCEEDED(hr)) {
// Set the stream back to its starting position.
LARGE_INTEGER pos;
pos.QuadPart = 0;
pStream->Seek((LARGE_INTEGER)pos, STREAM_SEEK_SET, NULL);
hr = pStream->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(&pUnk));
vHeadTxtStream.vt = VT_UNKNOWN;
vHeadTxtStream.punkVal = pUnk;
}
rgIndices = 0;
SafeArrayPutElement(psaHeadFoot, &rgIndices, static_cast<void *>(&vHeadStr));
rgIndices = 1;
SafeArrayPutElement(psaHeadFoot, &rgIndices, static_cast<void *>(&vFootStr));
rgIndices = 2;
SafeArrayPutElement(psaHeadFoot, &rgIndices, static_cast<void *>(&vHeadTxtStream));
//NOTE: Currently, the SAFEARRAY variant must be passed by using
// the VT_BYREF vartype when you call the ExecWeb method.
VARIANT vArg;
VariantInit(&vArg);
vArg.vt = VT_ARRAY | VT_BYREF;
vArg.parray = psaHeadFoot;
hr = webOC->ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, &vArg, NULL);
if (FAILED(hr)) {
ATLTRACE(_T("DoPrint: Call to WebBrowser's ExecWB failed: %lX\n"), hr);
goto cleanup;
}
return 1;
//WebBrowser control will clean up the SAFEARRAY after printing.
cleanup:
VariantClear(&vHeadStr);
VariantClear(&vFootStr);
VariantClear(&vHeadTxtStream);
if (psaHeadFoot) {
SafeArrayDestroy(psaHeadFoot);
}
if (sMem) {
CoTaskMemFree(sMem);
}
if (hG != NULL) {
GlobalFree(hG);
}
if (pStream != NULL) {
pStream->Release();
pStream = NULL;
}
bHandled = TRUE;
return 0;
} REFERENCESFor more information about developing Web-based solutions for Microsoft Internet Explorer, visit the following Microsoft Web sites:
Modification Type: | Major | Last Reviewed: | 5/11/2006 |
---|
Keywords: | kbFAQ kbhowto kbprint kbWebBrowser KB267240 |
---|
|