C++ IE9未能在BHO的HTMLWindow2上触发onscroll事件

C++ IE9未能在BHO的HTMLWindow2上触发onscroll事件,c++,internet-explorer,events,bho,C++,Internet Explorer,Events,Bho,IE在使用文档模式时可以触发onscroll事件:IE7或IE8,但在使用文档模式时,未能触发onscroll事件:IE9。我还在documentElement上注册onscroll事件,它的反应也是一样的 BHO类使用: public IDispEventImpl<3, CHelloWorldBHO, &DIID_HTMLWindowEvents2, &LIBID_MSHTML, 4, 0>. 然后将其通知文档完成中的窗口对象: CComQIPtr<IHT

IE在使用文档模式时可以触发onscroll事件:IE7或IE8,但在使用文档模式时,未能触发onscroll事件:IE9。我还在documentElement上注册onscroll事件,它的反应也是一样的

BHO类使用:

public IDispEventImpl<3, CHelloWorldBHO, &DIID_HTMLWindowEvents2, &LIBID_MSHTML, 4, 0>. 
然后将其通知文档完成中的窗口对象:

CComQIPtr<IHTMLDocument2> spHTMLDoc = spDispDoc;
CComQIPtr<IHTMLWindow2> spTempWindow2;
spHTMLDoc->get_parentWindow(&spTempWindow2);

IDispEventImpl<3, CHelloWorldBHO, &DIID_HTMLWindowEvents2, &LIBID_MSHTML, 4, 0>::DispEventAdvise(spTempWindow2);
CComQIPtr spHTMLDoc=spDispDoc;
CComQIPtr spTempWindow2;
spHTMLDoc->get_parentWindow(&spTempWindow2);
IDispEventImpl::DispEventAdvise(spTempWindow2);

我研究这个问题已经有一段时间了。有什么想法吗?非常感谢

对于IE9和document mode=IE9,您需要使用“新”事件

hr=\u spDocument->get\u parentWindow(重新解释cast(&u spWindow));
如果(成功(hr)和&&U spWindow)
{
//如果文档模式低于9,我们可以使用旧的方式进行OnScrolleEvent
如果(_uiDocumentMode<9)
{
hr=IDispEventImpl::DispEventAdvise(_spWindow);
如果(成功(hr))
{
...
}
}
其他的
{
首席执行官斯皮文特目标;
hr=\u spWindow->QueryInterface(IID\u IEventTarget,reinterpret\u cast(&spieventarget));
如果(成功(hr)和&spIEventTarget)
{   
_spEventScroll=new CIE9UIEvent();//此类必须从IDispatchEx派生
指挥调度;
HRESULT hr=\u spEventScroll->QueryInterface(IID_IDispatch,reinterprept_cast(&spIDispatch));//获取IDispatch
if(成功(人力资源)和调度)
{
//如果使用_spEventScroll而不是spIDispatch,将发生异常!!!
hr=\u spIEventTarget->addEventListener(\u bstr\u t(“滚动”),spIDispatch,VARIANT\u TRUE);
如果(成功(hr))
{
...
}
}
}
}
}
现在在您的派生类上

//////////////////////////////////////////////////////////////////////
// InvokeEx
//////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CIE9UIEvent::InvokeEx(             
            __in  DISPID dispIdMember,            
            __in  LCID lcid,            
            __in  WORD wFlags,            
            __in  DISPPARAMS* pDispParams,            
            __out_opt  VARIANT *pvarRes,            
            __out_opt  EXCEPINFO *pei,            
            __in_opt  IServiceProvider *pspCaller)
{
    if(dispIdMember == 0 && pDispParams->cArgs == 2)
    {   
        if(pDispParams->rgvarg[1].vt == VT_DISPATCH && pDispParams->rgvarg[1].pdispVal)
        {
            CComPtr<IDOMEvent> spIDOMEvent;
            HRESULT hr = pDispParams->rgvarg[1].pdispVal->QueryInterface(IID_IDOMEvent, reinterpret_cast<void **>(&spIDOMEvent));
            if(SUCCEEDED(hr) && spIDOMEvent)
            {
                ...
            }
        }
    }

    return S_OK;
}
//////////////////////////////////////////////////////////////////////
//InvokeEx
//////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CIE9UIEvent::InvokeEx(
__在DISPID DISPID member中,
__在LCID LCID中,
__总而言之,
__在DISPPARAMS*pDispParams中,
__不适用变型*pvarRes,
__不包括,
__in_opt IServiceProvider*pspCaller)
{
如果(dispIdMember==0&&pDispParams->cArgs==2)
{   
如果(pDispParams->rgvarg[1].vt==vt\u调度&&pDispParams->rgvarg[1].pdispVal)
{
CComPtr spIDOMEvent;
HRESULT hr=pDispParams->rgvarg[1]。pdispVal->QueryInterface(IID_IDOMEvent,reinterpret_cast(&spIDOMEvent));
if(成功(hr)和SPIDOMENT)
{
...
}
}
}
返回S_OK;
}
最后一步是在类QueryInterface方法中添加IDispatchEx

//////////////////////////////////////////////////////////////////////
// QueryInterface
//////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CIE9EventListener::QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
    *ppvObject = NULL;
    if(IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = reinterpret_cast<void**>(this);

    if(IsEqualGUID(riid, IID_IDispatch))
        *ppvObject = reinterpret_cast<void**>(this);

    if(IsEqualGUID(riid, IID_IDispatchEx))
        *ppvObject = reinterpret_cast<void**>(this);


    if(*ppvObject)
    {
        ((IUnknown*)*ppvObject)->AddRef();
        return S_OK;
    }

    return E_NOINTERFACE;
}
//////////////////////////////////////////////////////////////////////
//查询接口
//////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CIE9EventListener::QueryInterface(refid-riid、\uuuuu-RPC\uu-deref\u-out-void、\uuuu-RPC\u-FAR*\uuuu-RPC\u-FAR*ppvObject)
{
*ppvObject=NULL;
if(IsEqualGUID(riid,IID_IUnknown))
*ppvObject=重新解释(本);
if(IsEqualGUID(riid,IID_-IDispatch))
*ppvObject=重新解释(本);
if(IsEqualGUID(riid,IID_IDispatchEx))
*ppvObject=重新解释(本);
如果(*ppvObject)
{
((IUnknown*)*ppvObject)->AddRef();
返回S_OK;
}
返回E_NOINTERFACE;
}
//////////////////////////////////////////////////////////////////////
// InvokeEx
//////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CIE9UIEvent::InvokeEx(             
            __in  DISPID dispIdMember,            
            __in  LCID lcid,            
            __in  WORD wFlags,            
            __in  DISPPARAMS* pDispParams,            
            __out_opt  VARIANT *pvarRes,            
            __out_opt  EXCEPINFO *pei,            
            __in_opt  IServiceProvider *pspCaller)
{
    if(dispIdMember == 0 && pDispParams->cArgs == 2)
    {   
        if(pDispParams->rgvarg[1].vt == VT_DISPATCH && pDispParams->rgvarg[1].pdispVal)
        {
            CComPtr<IDOMEvent> spIDOMEvent;
            HRESULT hr = pDispParams->rgvarg[1].pdispVal->QueryInterface(IID_IDOMEvent, reinterpret_cast<void **>(&spIDOMEvent));
            if(SUCCEEDED(hr) && spIDOMEvent)
            {
                ...
            }
        }
    }

    return S_OK;
}
//////////////////////////////////////////////////////////////////////
// QueryInterface
//////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CIE9EventListener::QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
    *ppvObject = NULL;
    if(IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = reinterpret_cast<void**>(this);

    if(IsEqualGUID(riid, IID_IDispatch))
        *ppvObject = reinterpret_cast<void**>(this);

    if(IsEqualGUID(riid, IID_IDispatchEx))
        *ppvObject = reinterpret_cast<void**>(this);


    if(*ppvObject)
    {
        ((IUnknown*)*ppvObject)->AddRef();
        return S_OK;
    }

    return E_NOINTERFACE;
}