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

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

问题描述

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

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