处理复选框的OnClick事件 [英] Handling an OnClick event of a checkbox
问题描述
我试图处理来自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(Lcheckbox_id_here),& elementCheckbox);
if(!elementCheckbox)
return;
if(!m_fCheckboxAdvised)
{
//注册从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
?
您没有您请求的连接点,因此 CONNECT_E_NOCONNECTION
失败。
代替为具有多个接口的HTML元素实现连接点客户端,您可能更喜欢备用路由,并在事件接收器对象上实现IDispatch,然后将接口指针指向HTML元素的 onclick
属性。您将获得 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(Lonresize,& vValue));
CDispatchEventSink
class is 此处,您会发现完整的示例项目(以及 SVN 链接)。 / p>
>
I'm trying to handle click events of a checkbox control from a BHO.
Here is my code:
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
}
}
Header file:
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
fails with hr = 0x80040200
. What am I doing wrong?
Also, when should I call DispEventUnadvise
?
You don't have the connection point you request, hence the CONNECT_E_NOCONNECTION
failure.
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.
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
class is here, and you will find full sample project there as well (also, SVN link).
这篇关于处理复选框的OnClick事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!