处理复选框的 OnClick 事件 [英] Handling an OnClick event of a checkbox
问题描述
我正在尝试处理来自 BHO 的复选框控件的点击事件.
I'm trying to handle click events of a checkbox control from a 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
.我做错了什么?
DispEventAdvise
fails with hr = 0x80040200
. What am I doing wrong?
另外,我应该什么时候调用DispEventUnadvise
?
Also, when should I call DispEventUnadvise
?
推荐答案
您没有请求的连接点,因此 CONNECT_E_NOCONNECTION
失败.
You don't have the connection point you request, hence the CONNECT_E_NOCONNECTION
failure.
与其为具有多个接口的 HTML 元素实现连接点客户端,您可能更喜欢替代路由并在事件接收器对象上实现 IDispatch,然后将接口指针分配给 onclick
属性的 HTML 元素.您将在事件上获得 IDispatch::Invoke
调用.
Instead of implementing a connection point client for HTML elements with a multitude of interfaces, you might prefer an alternate route and implement IDispatch on your event sink object, and then assign the interface pointer to onclick
property of the HTML element. You will get IDispatch::Invoke
call on the event.
这是一个代码片段,用于创建合适的 IDispatch
实现实例,并通过 C++ 代码设置 onresize
属性:
Here is a code snippet for you for creating an instance of suitable IDispatch
implemetnation, and setting onresize
property via C++ code:
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
类是 此处,您还可以在此处找到完整的示例项目(还有 SVN 链接).
CDispatchEventSink
class is here, and you will find full sample project there as well (also, SVN link).
这篇关于处理复选框的 OnClick 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!