【发布时间】:2014-02-01 02:18:48
【问题描述】:
我正在尝试处理来自 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);
/*...*/
};
DispEventAdvise 失败,hr = 0x80040200。我做错了什么?
另外,我应该什么时候打电话给DispEventUnadvise?
【问题讨论】:
-
HTML 元素没有实现连接点,所以你有
CONNECT_E_NOCONNECTION失败。相反,您需要在对象上实现IDispatch,并将接口指针分配给HTML 元素的onclick属性。您将在活动中收到IDispatch::Invoke电话。 -
@RomanR.,感谢您的评论。我对 BHO 和/或 ATL 不是很有经验。如果您可以提供一个最小的示例或包含更多信息的链接,那将非常有帮助。提前致谢。
-
@RomanR。 HTML 元素也实现了连接点。但是它们使用起来有些不方便,因为不同类型的元素接受不同的源接口:没有一个单一的接收器可以建议所有它们。例如。
<input type="checkbox">由支持以下源接口的HTMLInputElementcoclass 表示:HTMLInputTextElementEvents、HTMLInputTextElementEvents2、HTMLOptionButtonElementEvents、HTMLButtonElementEvents- 但 不是HTMLElementEvents2OP 正在尝试水槽。 -
@IgorTandetnik:谢谢,我在这里更正了。
-
@Paul 将建议的元素存储在向量或列表中。通过计时器轮询时,您可以使用 IsSameObject 检查元素是否在列表中。通过定时器轮询很有用,即使在没有刷新的情况下也是如此。很多页面在“随机”时刻对 DOM 做了一些奇怪的事情。