http://support.microsoft.com/kb/261003
当其中一个脚本引擎遇到未处理的错误时,它将转发到 web 浏览器控件,然后查询以查看容器已经实现了宿主其容器的错误。如果容器已实现宿主,web 浏览器控件调用CGID_DocHostCommandHandler (这在 Mshtmhst.h 文件中定义) 的命令组 ID 和OLECMDID_SHOWSCRIPTERROR的命令 ID 的IOleCommandTarget::Exec方法。如果主机不会返回S_OK,MSHTML 显示默认的"此页上出现错误"错误信息。
下面的代码演示如何实现文档对象模型中检索信息时此命令 id 的处理程序。此代码不会说明了错误处理。
注: 如果用户已清除在 Internet 选项 下的 高级 选项卡中的 禁用脚本调试 复选框,将不会调用此方法。
STDMETHODIMP CMyBrowser::Exec( const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANTARG* pvaIn, VARIANTARG* pvaOut ) { HRESULT hr = S_OK; if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler)) { switch (nCmdID) { case OLECMDID_SHOWSCRIPTERROR: { IHTMLDocument2* pDoc = NULL; IHTMLWindow2* pWindow = NULL; IHTMLEventObj* pEventObj = NULL; BSTR rgwszNames[5] = { SysAllocString(L"errorLine"), SysAllocString(L"errorCharacter"), SysAllocString(L"errorCode"), SysAllocString(L"errorMessage"), SysAllocString(L"errorUrl") }; DISPID rgDispIDs[5]; VARIANT rgvaEventInfo[5]; DISPPARAMS params; BOOL fContinueRunningScripts = true; int i; params.cArgs = 0; params.cNamedArgs = 0; // Get the document that is currently being viewed. hr = pvaIn->punkVal->QueryInterface(IID_IHTMLDocument2, (void **) &pDoc); // Get document.parentWindow. hr = pDoc->get_parentWindow(&pWindow); pDoc->Release(); // Get the window.event object. hr = pWindow->get_event(&pEventObj); // Get the error info from the window.event object. for (i = 0; i < 5; i++) { // Get the property's dispID. hr = pEventObj->GetIDsOfNames(IID_NULL, &rgwszNames[i], 1, LOCALE_SYSTEM_DEFAULT, &rgDispIDs[i]); // Get the value of the property. hr = pEventObj->Invoke(rgDispIDs[i], IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, ¶ms, &rgvaEventInfo[i], NULL, NULL); SysFreeString(rgwszNames[i]); } // At this point, you would normally alert the user with // the information about the error, which is now contained // in rgvaEventInfo[]. Or, you could just exit silently. (*pvaOut).vt = VT_BOOL; if (fContinueRunningScripts) { // Continue running scripts on the page. (*pvaOut).boolVal = VARIANT_TRUE; } else { // Stop running scripts on the page. (*pvaOut).boolVal = VARIANT_FALSE; } break; } default: hr = OLECMDERR_E_NOTSUPPORTED; break; } } else { hr = OLECMDERR_E_UNKNOWNGROUP; } return (hr); }
如何重写的 MFC 控件容器接口方法看这里:http://blog.youkuaiyun.com/mail_cm/article/details/7817624