SYMPTOMS
When you write a WebBrowser control host in Visual C++, you may use the information in the following Microsoft Knowledge Base article to generate notification of script errors:
261003 How to handle script errors as a WebBrowser control host
However, this notification may be inconsistent: In both Internet Explorer 5.5 and Internet Explorer 6.0, the host may receive the notification on certain installations but not on others. Or, on Microsoft Windows platforms with Internet Explorer 5.5 installed, you may not receive the first notification, yet all subsequent notifications properly trigger the call to the
Exec method.
CAUSE
This behavior is by design in Internet Explorer 6.0. The
OLECMDID_SHOWSCRIPTERROR command ID does not fire if the
Disable Script Debugging check box is cleared (on the
Tools menu, click
Internet Options, and then click
Advanced). The behavior is a bug in Internet Explorer 5.5 that was resolved in Internet Explorer 6.0.
For additional information about this issue, click the following article number to view the article in the Microsoft Knowledge Base:
263100
OL2000: Hyperlink does not open a new instance of your Internet browser
RESOLUTION
Although you can programmatically configure the registry setting behind the
Disable Script Debugging check box, this affects the behavior of Internet Explorer and all other WebBrowser hosts on the computer, not just
your WebBrowser host. Fortunately, you can guarantee that the
OLECMDID_SHOWSCRIPTERROR message fires on every computer, regardless of configuration, by injecting a script-based
onerror event handler into the current document. This can be done from your host's
DWebBrowser2::DocumentComplete() event handler.
For additional information about how to sink events in both Microsoft Foundation Classes (MFC) and the Active Template Library (ATL), click the following article number to view the article in the Microsoft Knowledge Base:
247073
CustWBC.exe: ATL HTML control customizes the WebBrowser control
For a sample application that demonstrates how to sink events for Internet Explorer from an MFC application, visit the following MSDN Web site:
The following sample code was written for an MFC dialog box application; the body can be cut and pasted, along with the macros, into either an ATL or MFC host:
#define CHECK_HR(hr,label) \
if(FAILED(hr)) \
{ goto label; \
}
#define RRELEASE(ptr) \
if(ptr) \
{ ptr->Release(); \
ptr = NULL; \
}
// Get the DOM associated with the WebBrowser that threw this event, and
// inject an onerror tag into the page in hopes of receiving an
// OLECMDID_SHOWSCRIPTERROR message. (This is a bug in Internet Explorer 6.)
// NOTE: pBrowser is the IWebBrowser2 for the FRAME, IFRAME, or primary
// that just finished loading our document. If you have a FRAMESET with
// three FRAMEs, you will see this handler called four times: once for
// each FRAME and once for the FRAMESET after all FRAMEs have loaded.
// We're sinking each individual FRAME in this sample; to sink only the
// topmost FRAME, test the IUnknown of our m_pBrowser against the IUnknown
// of this method's pBrowser, and sink only when these two are equal.
void CSimpleBrowserDlg::OnDocumentComplete(LPDISPATCH pBrowser, LPVARIANT url)
{
IWebBrowser2 *thisBrowser = NULL;
IDispatch *docDisp = NULL;
IHTMLDocument3 *doc = NULL;
IHTMLElement *elem = NULL;
HRESULT hr = S_OK;
hr = pBrowser->QueryInterface(IID_IWebBrowser2, reinterpret_cast<void **>(&thisBrowser));
CHECK_HR(hr, cleanup);
hr = thisBrowser->get_Document(&docDisp);
CHECK_HR(hr, cleanup);
hr = docDisp->QueryInterface(IID_IHTMLDocument3, reinterpret_cast<void**>(&doc));
CHECK_HR(hr, cleanup);
RRELEASE(docDisp);
// Get the documentElement for the document object, and then call
// IHTMLElement::insertAdjacentHTML() to add the onerror SCRIPT
// handler tag.
hr = doc->get_documentElement(&elem);
CHECK_HR(hr, cleanup);
// NOTE: The  , or some other visible HTML, is required. Internet Explorer will not
// parse and recognize the script block without some visual HTML to
// accompany it.
hr = elem->insertAdjacentHTML(L"afterBegin", L" <SCRIPT For='window' Event='onerror'>var noOp = null;</SCRIPT>");
// Cleanup.
cleanup:
RRELEASE(elem);
RRELEASE(thisBrowser);
RRELEASE(doc);
}