#include "StdAfx.h" #include "UIWebBrowser.h" #include #include #include "../Utils/downloadmgr.h" #include DuiLib::CWebBrowserUI::CWebBrowserUI() : m_pWebBrowser2(NULL) , _pHtmlWnd2(NULL) , m_pWebBrowserEventHandler(NULL) , m_bAutoNavi(true) , m_dwRef(0) , m_dwCookie(0) { m_clsid=CLSID_WebBrowser; m_sHomePage.Empty(); } bool DuiLib::CWebBrowserUI::DoCreateControl() { if (!CActiveXUI::DoCreateControl()) return false; GetManager()->AddTranslateAccelerator(this); GetControl(IID_IWebBrowser2,(LPVOID*)&m_pWebBrowser2); if ( m_bAutoNavi /*&& !m_sHomePage.IsEmpty()*/) { this->Navigate2(/*m_sHomePage*/_T("about:blank")); } RegisterEventHandler(TRUE); return true; } void DuiLib::CWebBrowserUI::ReleaseControl() { m_bCreated=false; GetManager()->RemoveTranslateAccelerator(this); RegisterEventHandler(FALSE); } DuiLib::CWebBrowserUI::~CWebBrowserUI() { ReleaseControl(); } STDMETHODIMP DuiLib::CWebBrowserUI::GetTypeInfoCount( UINT *iTInfo ) { *iTInfo = 0; return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo ) { return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::GetIDsOfNames( REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid,DISPID *rgDispId ) { return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid,WORD wFlags, DISPPARAMS* pDispParams,VARIANT* pVarResult, EXCEPINFO* pExcepInfo,UINT* puArgErr ) { if ((riid != IID_NULL)) return E_INVALIDARG; switch(dispIdMember) { case DISPID_BEFORENAVIGATE2: BeforeNavigate2( pDispParams->rgvarg[6].pdispVal, pDispParams->rgvarg[5].pvarVal, pDispParams->rgvarg[4].pvarVal, pDispParams->rgvarg[3].pvarVal, pDispParams->rgvarg[2].pvarVal, pDispParams->rgvarg[1].pvarVal, pDispParams->rgvarg[0].pboolVal); break; case DISPID_COMMANDSTATECHANGE: CommandStateChange( pDispParams->rgvarg[1].lVal, pDispParams->rgvarg[0].boolVal); break; case DISPID_NAVIGATECOMPLETE2: NavigateComplete2( pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal); break; case DISPID_NAVIGATEERROR: NavigateError( pDispParams->rgvarg[4].pdispVal, pDispParams->rgvarg[3].pvarVal, pDispParams->rgvarg[2].pvarVal, pDispParams->rgvarg[1].pvarVal, pDispParams->rgvarg[0].pboolVal); break; case DISPID_STATUSTEXTCHANGE: break; // case DISPID_NEWWINDOW2: // break; case DISPID_NEWWINDOW3: NewWindow3( pDispParams->rgvarg[4].ppdispVal, pDispParams->rgvarg[3].pboolVal, pDispParams->rgvarg[2].uintVal, pDispParams->rgvarg[1].bstrVal, pDispParams->rgvarg[0].bstrVal); break; case DISPID_DOCUMENTCOMPLETE: DocmentComplete( pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal); break; case DISPID_NEWWINDOW2: NewWindow2(pDispParams->rgvarg[0].pboolVal, pDispParams->rgvarg[5].bstrVal); break; // case DISPID_PROPERTYCHANGE: // if (pDispParams->cArgs>0 && pDispParams->rgvarg[0].vt == VT_BSTR) { // TRACE(_T("PropertyChange(%s)\n"), pDispParams->rgvarg[0].bstrVal); // } // break; default: return DISP_E_MEMBERNOTFOUND; } return S_OK; } STDMETHODIMP DuiLib::CWebBrowserUI::QueryInterface( REFIID riid, LPVOID *ppvObject ) { *ppvObject = NULL; if( riid == IID_IDocHostUIHandler) *ppvObject = static_cast(this); else if( riid == IID_IDispatch) *ppvObject = static_cast(this); else if( riid == IID_IServiceProvider) *ppvObject = static_cast(this); else if (riid == IID_IOleCommandTarget) *ppvObject = static_cast(this); if( *ppvObject != NULL ) AddRef(); return *ppvObject == NULL ? E_NOINTERFACE : S_OK; } STDMETHODIMP_(ULONG) DuiLib::CWebBrowserUI::AddRef() { InterlockedIncrement(&m_dwRef); return m_dwRef; } STDMETHODIMP_(ULONG) DuiLib::CWebBrowserUI::Release() { ULONG ulRefCount = InterlockedDecrement(&m_dwRef); return ulRefCount; } void DuiLib::CWebBrowserUI::Navigate2( LPCTSTR lpszUrl ) { if (lpszUrl == NULL) return; if (m_pWebBrowser2) { CVariant url; url.vt=VT_BSTR; url.bstrVal=T2BSTR(lpszUrl); HRESULT hr = m_pWebBrowser2->Navigate2(&url, NULL, NULL, NULL, NULL); } } void DuiLib::CWebBrowserUI::Refresh() { if (m_pWebBrowser2) { m_pWebBrowser2->Refresh(); } } void DuiLib::CWebBrowserUI::GoBack() { if (m_pWebBrowser2) { m_pWebBrowser2->GoBack(); } } void DuiLib::CWebBrowserUI::GoForward() { if (m_pWebBrowser2) { m_pWebBrowser2->GoForward(); } } /// DWebBrowserEvents2 void DuiLib::CWebBrowserUI::BeforeNavigate2( IDispatch *pDisp,VARIANT *&url,VARIANT *&Flags,VARIANT *&TargetFrameName,VARIANT *&PostData,VARIANT *&Headers,VARIANT_BOOL *&Cancel ) { if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->BeforeNavigate2(pDisp,url,Flags,TargetFrameName,PostData,Headers,Cancel); } } void DuiLib::CWebBrowserUI::NavigateError( IDispatch *pDisp,VARIANT * &url,VARIANT *&TargetFrameName,VARIANT *&StatusCode,VARIANT_BOOL *&Cancel ) { if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->NavigateError(pDisp,url,TargetFrameName,StatusCode,Cancel); } } void DuiLib::CWebBrowserUI::NavigateComplete2( IDispatch *pDisp,VARIANT *&url ) { CComPtr spDoc; m_pWebBrowser2->get_Document(&spDoc); if (spDoc) { CComQIPtr spCustomDoc(spDoc); if (spCustomDoc) spCustomDoc->SetUIHandler(this); } if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->NavigateComplete2(pDisp,url); } } void DuiLib::CWebBrowserUI::ProgressChange( LONG nProgress, LONG nProgressMax ) { if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->ProgressChange(nProgress,nProgressMax); } } void DuiLib::CWebBrowserUI::NewWindow3( IDispatch **pDisp, VARIANT_BOOL *&Cancel, DWORD dwFlags, BSTR bstrUrlContext, BSTR bstrUrl ) { if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->NewWindow3(pDisp,Cancel,dwFlags,bstrUrlContext,bstrUrl); } } void DuiLib::CWebBrowserUI::CommandStateChange(long Command,VARIANT_BOOL Enable) { if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->CommandStateChange(Command,Enable); } } void DuiLib::CWebBrowserUI::NewWindow2(VARIANT_BOOL *&Cancel, BSTR bstrUrl) { if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->NewWindow2(Cancel, bstrUrl); } } void DuiLib::CWebBrowserUI::DocmentComplete(IDispatch *pDisp, VARIANT *&url) { if (m_pWebBrowserEventHandler) { m_pWebBrowserEventHandler->DocmentComplete(pDisp, url); } } // IDownloadManager STDMETHODIMP DuiLib::CWebBrowserUI::Download( /* [in] */ IMoniker *pmk, /* [in] */ IBindCtx *pbc, /* [in] */ DWORD dwBindVerb, /* [in] */ LONG grfBINDF, /* [in] */ BINDINFO *pBindInfo, /* [in] */ LPCOLESTR pszHeaders, /* [in] */ LPCOLESTR pszRedir, /* [in] */ UINT uiCP ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->Download(pmk,pbc,dwBindVerb,grfBINDF,pBindInfo,pszHeaders,pszRedir,uiCP); } return S_OK; } // IDocHostUIHandler STDMETHODIMP DuiLib::CWebBrowserUI::ShowContextMenu( DWORD dwID, POINT* pptPosition, IUnknown* pCommandTarget, IDispatch* pDispatchObjectHit ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->ShowContextMenu(dwID,pptPosition,pCommandTarget,pDispatchObjectHit); } return S_FALSE; } STDMETHODIMP DuiLib::CWebBrowserUI::GetHostInfo( DOCHOSTUIINFO* pInfo ) { if (pInfo) { pInfo->dwFlags |= DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_DIV_BLOCKDEFAULT; } if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->GetHostInfo(pInfo); } return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::ShowUI( DWORD dwID, IOleInPlaceActiveObject* pActiveObject, IOleCommandTarget* pCommandTarget, IOleInPlaceFrame* pFrame, IOleInPlaceUIWindow* pDoc ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->ShowUI(dwID,pActiveObject,pCommandTarget,pFrame,pDoc); } return S_OK; } STDMETHODIMP DuiLib::CWebBrowserUI::HideUI() { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->HideUI(); } return S_OK; } STDMETHODIMP DuiLib::CWebBrowserUI::UpdateUI() { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->UpdateUI(); } return S_OK; } STDMETHODIMP DuiLib::CWebBrowserUI::EnableModeless( BOOL fEnable ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->EnableModeless(fEnable); } return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::OnDocWindowActivate( BOOL fActivate ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->OnDocWindowActivate(fActivate); } return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::OnFrameWindowActivate( BOOL fActivate ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->OnFrameWindowActivate(fActivate); } return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::ResizeBorder( LPCRECT prcBorder, IOleInPlaceUIWindow* pUIWindow, BOOL fFrameWindow ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->ResizeBorder(prcBorder,pUIWindow,fFrameWindow); } return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::TranslateAccelerator( LPMSG lpMsg, const GUID* pguidCmdGroup, DWORD nCmdID ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->TranslateAccelerator(lpMsg,pguidCmdGroup,nCmdID); } return S_FALSE; } LRESULT DuiLib::CWebBrowserUI::TranslateAccelerator( MSG *pMsg ) { if(pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) return S_FALSE; if( m_pWebBrowser2 == NULL ) return E_NOTIMPL; // 当前Web窗口不是焦点,不处理加速键 BOOL bIsChild = FALSE; HWND hTempWnd = NULL; HWND hWndFocus = ::GetFocus(); hTempWnd = hWndFocus; while(hTempWnd != NULL) { if(hTempWnd == m_hwndHost) { bIsChild = TRUE; break; } hTempWnd = ::GetParent(hTempWnd); } if(!bIsChild) return S_FALSE; IOleInPlaceActiveObject *pObj; if (FAILED(m_pWebBrowser2->QueryInterface(IID_IOleInPlaceActiveObject, (LPVOID *)&pObj))) return S_FALSE; HRESULT hResult = pObj->TranslateAccelerator(pMsg); pObj->Release(); return hResult; } STDMETHODIMP DuiLib::CWebBrowserUI::GetOptionKeyPath( LPOLESTR* pchKey, DWORD dwReserved ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->GetOptionKeyPath(pchKey,dwReserved); } return E_NOTIMPL; } STDMETHODIMP DuiLib::CWebBrowserUI::GetDropTarget( IDropTarget* pDropTarget, IDropTarget** ppDropTarget ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->GetDropTarget(pDropTarget,ppDropTarget); } return S_FALSE; // 使用系统拖拽 } STDMETHODIMP DuiLib::CWebBrowserUI::GetExternal( IDispatch** ppDispatch ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->GetExternal(ppDispatch); } return S_FALSE; } STDMETHODIMP DuiLib::CWebBrowserUI::TranslateUrl( DWORD dwTranslate, OLECHAR* pchURLIn, OLECHAR** ppchURLOut ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->TranslateUrl(dwTranslate,pchURLIn,ppchURLOut); } else { *ppchURLOut = 0; return E_NOTIMPL; } } STDMETHODIMP DuiLib::CWebBrowserUI::FilterDataObject( IDataObject* pDO, IDataObject** ppDORet ) { if (m_pWebBrowserEventHandler) { return m_pWebBrowserEventHandler->FilterDataObject(pDO,ppDORet); } else { *ppDORet = 0; return E_NOTIMPL; } } void DuiLib::CWebBrowserUI::SetWebBrowserEventHandler( CWebBrowserEventHandler* pEventHandler ) { if ( pEventHandler!=NULL && m_pWebBrowserEventHandler!=pEventHandler) m_pWebBrowserEventHandler=pEventHandler; } void DuiLib::CWebBrowserUI::Refresh2( int Level ) { CVariant vLevel; vLevel.vt=VT_I4; vLevel.intVal=Level; m_pWebBrowser2->Refresh2(&vLevel); } void DuiLib::CWebBrowserUI::SetAttribute( LPCTSTR pstrName, LPCTSTR pstrValue ) { if (_tcscmp(pstrName, _T("homepage")) == 0) { m_sHomePage = pstrValue; } else if (_tcscmp(pstrName, _T("autonavi"))==0) { m_bAutoNavi = (_tcscmp(pstrValue, _T("true")) == 0); } else CActiveXUI::SetAttribute(pstrName, pstrValue); } void DuiLib::CWebBrowserUI::NavigateHomePage() { if (!m_sHomePage.IsEmpty()) this->NavigateUrl(m_sHomePage); } void DuiLib::CWebBrowserUI::NavigateUrl( LPCTSTR lpszUrl ) { if (m_pWebBrowser2 && lpszUrl) { m_pWebBrowser2->Navigate((BSTR)SysAllocString(T2BSTR(lpszUrl)),NULL,NULL,NULL,NULL); } } bool DuiLib::CWebBrowserUI::CallJScript(const CDuiString& strFunc, const CDuiString& param, VARIANT* pVarResult) { CComPtr pScript; IDispatch* pDp = NULL; HRESULT hr; if (m_pWebBrowser2) hr = m_pWebBrowser2->get_Document(&pDp); if (FAILED(hr)) return NULL; CComQIPtr pHtmlDoc2 = pDp; if (pHtmlDoc2 == NULL) return false; //获取脚本对象 pHtmlDoc2->get_Script(&pScript); if (NULL == pScript) { return false; } CComBSTR bstrMember(strFunc); DISPID dispid; hr = pScript->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid); if (!SUCCEEDED(hr)) { return false; } DISPPARAMS dispparams; memset(&dispparams, 0, sizeof(DISPPARAMS)); dispparams.cArgs = 1; dispparams.rgvarg = new VARIANT[dispparams.cArgs]; CComBSTR bstr(param); bstr.CopyTo(&dispparams.rgvarg[0].bstrVal); dispparams.rgvarg[0].vt = VT_BSTR; dispparams.cNamedArgs = 0; EXCEPINFO excepInfo; memset(&excepInfo, 0, sizeof(EXCEPINFO)); CComVariant vaResult; // initialize to invalid arg UINT nArgErr = (UINT)-1; // 执行js代码 hr = pScript->Invoke(dispid, IID_NULL, 0 , DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo, &nArgErr); delete[] dispparams.rgvarg; if (!SUCCEEDED(hr)) { return false; } return true; } LPCTSTR DuiLib::CWebBrowserUI::GetClass() const { return _T("WebBrowserUI"); } LPVOID DuiLib::CWebBrowserUI::GetInterface( LPCTSTR pstrName ) { if( _tcscmp(pstrName, DUI_CTR_WEBBROWSER) == 0 ) return static_cast(this); return CActiveXUI::GetInterface(pstrName); } void DuiLib::CWebBrowserUI::SetHomePage( LPCTSTR lpszUrl ) { m_sHomePage.Format(_T("%s"),lpszUrl); } LPCTSTR DuiLib::CWebBrowserUI::GetHomePage() { return m_sHomePage; } void DuiLib::CWebBrowserUI::SetAutoNavigation( bool bAuto /*= TRUE*/ ) { if (m_bAutoNavi==bAuto) return; m_bAutoNavi=bAuto; } bool DuiLib::CWebBrowserUI::IsAutoNavigation() { return m_bAutoNavi; } STDMETHODIMP DuiLib::CWebBrowserUI::QueryService( REFGUID guidService, REFIID riid, void** ppvObject ) { HRESULT hr = E_NOINTERFACE; *ppvObject = NULL; if ( guidService == SID_SDownloadManager && riid == IID_IDownloadManager) { *ppvObject = this; return S_OK; } return hr; } HRESULT DuiLib::CWebBrowserUI::RegisterEventHandler( BOOL inAdvise ) { CComPtr pWebBrowser; CComPtr pCPC; CComPtr pCP; HRESULT hr = GetControl(IID_IWebBrowser2, (void**)&pWebBrowser); if (FAILED(hr)) return hr; hr=pWebBrowser->QueryInterface(IID_IConnectionPointContainer,(void **)&pCPC); if (FAILED(hr)) return hr; hr=pCPC->FindConnectionPoint(DIID_DWebBrowserEvents2,&pCP); if (FAILED(hr)) return hr; if (inAdvise) { hr = pCP->Advise((IDispatch*)this, &m_dwCookie); } else { hr = pCP->Unadvise(m_dwCookie); } return hr; } DISPID DuiLib::CWebBrowserUI::FindId( IDispatch *pObj, LPOLESTR pName ) { DISPID id = 0; if(FAILED(pObj->GetIDsOfNames(IID_NULL,&pName,1,LOCALE_SYSTEM_DEFAULT,&id))) id = -1; return id; } HRESULT DuiLib::CWebBrowserUI::InvokeMethod( IDispatch *pObj, LPOLESTR pMehtod, VARIANT *pVarResult, VARIANT *ps, int cArgs ) { DISPID dispid = FindId(pObj, pMehtod); if(dispid == -1) return E_FAIL; DISPPARAMS dispparams; dispparams.cArgs = cArgs; dispparams.rgvarg = ps; dispparams.cNamedArgs = 0; dispparams.rgdispidNamedArgs = NULL; return pObj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, pVarResult, NULL, NULL); } HRESULT DuiLib::CWebBrowserUI::GetProperty( IDispatch *pObj, LPOLESTR pName, VARIANT *pValue ) { DISPID dispid = FindId(pObj, pName); if(dispid == -1) return E_FAIL; DISPPARAMS ps; ps.cArgs = 0; ps.rgvarg = NULL; ps.cNamedArgs = 0; ps.rgdispidNamedArgs = NULL; return pObj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &ps, pValue, NULL, NULL); } HRESULT DuiLib::CWebBrowserUI::SetProperty( IDispatch *pObj, LPOLESTR pName, VARIANT *pValue ) { DISPID dispid = FindId(pObj, pName); if(dispid == -1) return E_FAIL; DISPPARAMS ps; ps.cArgs = 1; ps.rgvarg = pValue; ps.cNamedArgs = 0; ps.rgdispidNamedArgs = NULL; return pObj->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &ps, NULL, NULL, NULL); } IDispatch* DuiLib::CWebBrowserUI::GetHtmlWindow() { IDispatch* pDp = NULL; HRESULT hr; if (m_pWebBrowser2) hr=m_pWebBrowser2->get_Document(&pDp); if (FAILED(hr)) return NULL; CComQIPtr pHtmlDoc2 = pDp; if (pHtmlDoc2 == NULL) return NULL; hr=pHtmlDoc2->get_parentWindow(&_pHtmlWnd2); if (FAILED(hr)) return NULL; IDispatch *pHtmlWindown = NULL; hr=_pHtmlWnd2->QueryInterface(IID_IDispatch, (void**)&pHtmlWindown); if (FAILED(hr)) return NULL; return pHtmlWindown; } IWebBrowser2* DuiLib::CWebBrowserUI::GetWebBrowser2( void ) { return m_pWebBrowser2; } HRESULT STDMETHODCALLTYPE DuiLib::CWebBrowserUI::QueryStatus( __RPC__in_opt const GUID *pguidCmdGroup, ULONG cCmds, __RPC__inout_ecount_full(cCmds ) OLECMD prgCmds[ ], __RPC__inout_opt OLECMDTEXT *pCmdText ) { HRESULT hr = OLECMDERR_E_NOTSUPPORTED; return hr; } HRESULT STDMETHODCALLTYPE DuiLib::CWebBrowserUI::Exec( __RPC__in_opt const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, __RPC__in_opt VARIANT *pvaIn, __RPC__inout_opt VARIANT *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); }