处理复选框的OnClick事件 [英] Handling an OnClick event of a checkbox

查看:987
本文介绍了处理复选框的OnClick事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图处理来自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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆