我正在开发 BHO,但在IE9中处理事件时遇到问题。我处理DocumentComplete (DISPID_DOCUMENTCOMPLETE),然后获得IHTMLWindow2及其IHTMLLocation以供将来操作。
代码(简化)
BHO 类使用
public IDispEventImpl<1, CBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 0>,
在SetSite中为浏览器事件提供建议
STDMETHODIMP CBHO::SetSite(IUnknown *punkSite)
{
if(punkSite != NULL)
{
CComQIPtr<IServiceProvider> pServiceProvider = punkSite;
pServiceProvider->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void**)&m_pWebBrowser);
IDispEventImpl<1, CBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 0>::DispEventAdvise(m_pWebBrowser);
}
...
}
水槽图
BEGIN_SINK_MAP(CBHO)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOWNLOADCOMPLETE, OnDownloadComplete)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2, OnNavigateComplete2)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_ONQUIT, OnQuit)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_WINDOWSTATECHANGED, OnWindowStateChanged)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_PROPERTYCHANGE, OnPropertyChange)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, BeforeNavigate2)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, DocumentComplete)
END_SINK_MAP()
DocumentComplete 事件处理程序:
void _stdcall CBHO::DocumentComplete( IDispatch *pDisp, VARIANT *URL)
{
CComQIPtr<IWebBrowser2> pBrowser(pDisp);
CComPtr<IDispatch> pDispDoc;
pBrowser->get_Document(&pDispDoc);
CComQIPtr<IHTMLDocument2> pDoc(pDispDoc);;
CComPtr<IHTMLWindow2> wnd;
pDoc->get_parentWindow(&wnd);
CComPtr<IHTMLLocation> pLoc;
HRESULT hr = wnd->get_location(&pLoc);
CComBSTR locHref;
hr=oLoc->get_href(&locHref); //"Access denied" error here
}
这在大多数情况下都是正确的,除了新选项卡中的打开链接(使用中键单击或带有 target="_blank" 的链接)。在这个新标签案例中,我得到 DocumentComplete 事件,然后得到指向 IHTMLWindow2 和 IHTMLLocation 的非 NULL wnd 指针,但是当我尝试使用 pLoc 指针进行任何操作时,例如获取 href 或其他任何内容时,我得到“访问被拒绝错误”错误. 另外,当检查doc.documentElement.outerHTML我得到了
<HTML><HEAD></HEAD>
<BODY>
<P> </P></BODY></HTML>
这不是目标页面的内容。
同时在 IE10 中,此代码按预期工作。
任何人都可以请教,我错在哪里以及为什么我在 DocumentComplete 中得到无效对象?