我正在尝试从BHO处理复选框控件的点击事件。
这是我的代码:
void STDMETHODCALLTYPE CMyBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
// ...
InitPage(pDocument);
}
void CMyBHO::InitPage(IHTMLDocument2 *pDocument)
{
CComQIPtr<IHTMLDocument3> document3 = pDocument;
CComPtr<IHTMLElement> elementCheckbox;
document3->getElementById(CComBSTR(L"checkbox_id_here"), &elementCheckbox);
if(!elementCheckbox)
return;
if(!m_fCheckboxAdvised)
{
// Register to sink events from HTMLDocumentEvents2.
hr = IHTMLElementEvents2Impl::DispEventAdvise(elementCheckbox);
if(SUCCEEDED(hr))
m_fCheckboxAdvised = TRUE;
else
ATLASSERT(0); // FAILS HERE, hr = 0x80040200
}
}
标题文件:
class ATL_NO_VTABLE CMyBHO :
/*...*/
public IDispEventImpl<1, CMyBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>,
public IDispEventImpl<2, CMyBHO, &DIID_HTMLElementEvents2, &LIBID_MSHTML, 4, 0>
{
typedef IDispEventImpl<1, CMyBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1> IDWebBrowserEvents2Impl;
typedef IDispEventImpl<2, CMyBHO, &DIID_HTMLElementEvents2, &LIBID_MSHTML, 4, 0> IHTMLElementEvents2Impl;
public:
/*...*/
BEGIN_SINK_MAP(CMyBHO)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
SINK_ENTRY_EX(2, DIID_HTMLElementEvents2, DISPID_HTMLELEMENTEVENTS2_ONCLICK, OnMouseClick)
END_SINK_MAP()
public:
STDMETHOD(SetSite)(IUnknown *pUnkSite);
// DWebBrowserEvents2
void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);
// HTMLDocumentEvents2
void STDMETHODCALLTYPE OnMouseClick(IHTMLEventObj *eventObj);
/*...*/
};
{p> DispEventAdvise
因hr = 0x80040200
而失败。我做错了什么?
此外,我应该何时致电DispEventUnadvise
?
答案 0 :(得分:2)
您没有请求的连接点,因此CONNECT_E_NOCONNECTION
失败。
您可能更喜欢备用路由并在事件接收器对象上实现IDispatch,然后将接口指针指定给HTML的onclick
属性,而不是为具有多个接口的HTML元素实现连接点客户端。元件。您将收到IDispatch::Invoke
来此活动的电话。
以下是一段代码片段,用于创建合适的IDispatch
实现的实例,并通过C ++代码设置onresize
属性:
CComPtr<IHTMLElement> pBodyElementA;
ATLENSURE_SUCCEEDED(pDocument->get_body(&pBodyElementA));
CComPtr<IDispatch> pSinkDispatch;
ATLENSURE_SUCCEEDED(CDispatchEventSink::CreateInstance(&pSinkDispatch));
CComVariant vValue = pSinkDispatch;
ATLENSURE_SUCCEEDED(reinterpret_cast<CComPtr<IDispatch>&>(pBodyElementA).
PutPropertyByName(L"onresize", &vValue));
CDispatchEventSink
课程为here,您也可以在那里找到完整的示例项目(同时,SVN链接)。