IE9无法在BHO中的HTMLWindow2上启动onscroll事件
IE9 fails to fire onscroll event on HTMLWindow2 in BHO
IE可以在使用文档模式:IE7或IE8时触发onscroll事件,但无法在使用文档模式IE9时触发onscroll event。我还在documentElement上注册了onscroll事件,它的反应也是一样的。
BHO类使用:
public IDispEventImpl<3, CHelloWorldBHO, &DIID_HTMLWindowEvents2, &LIBID_MSHTML, 4, 0>.
并击沉事件:
BEGIN_SINK_MAP(CHelloWorldBHO)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2, OnNavigateComplete2)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_WINDOWSTATECHANGED, OnWindowStateChanged)
SINK_ENTRY_EX(3, DIID_HTMLWindowEvents2, DISPID_HTMLWINDOWEVENTS2_ONSCROLL, OnScroll)
END_SINK_MAP()
然后将其告知文档完成中的窗口对象:
CComQIPtr<IHTMLDocument2> spHTMLDoc = spDispDoc;
CComQIPtr<IHTMLWindow2> spTempWindow2;
spHTMLDoc->get_parentWindow(&spTempWindow2);
IDispEventImpl<3, CHelloWorldBHO, &DIID_HTMLWindowEvents2, &LIBID_MSHTML, 4, 0>::DispEventAdvise(spTempWindow2);
我研究这个问题已经有一段时间了。有什么想法吗?非常感谢!
使用IE9和document-mode=IE9,您需要使用"new"Events。
hr = _spDocument->get_parentWindow(reinterpret_cast<IHTMLWindow2 **>(&_spWindow));
if (SUCCEEDED(hr) && _spWindow)
{
// If document mode is lower than 9 we can had the OnScrollEvent the old way
if(_uiDocumentMode < 9)
{
hr = IDispEventImpl<2, CIEPage, &DIID_HTMLWindowEvents2, &LIBID_MSHTML, 4, 0>::DispEventAdvise(_spWindow);
if(SUCCEEDED(hr))
{
...
}
}
else
{
CComPtr<IEventTarget> spIEventTarget;
hr = _spWindow->QueryInterface(IID_IEventTarget, reinterpret_cast<void **>(&spIEventTarget));
if (SUCCEEDED(hr) && spIEventTarget)
{
_spEventScroll = new CIE9UIEvent(); // This class must derive from IDispatchEx
CComPtr<IDispatch> spIDispatch;
HRESULT hr = _spEventScroll->QueryInterface(IID_IDispatch, reinterpret_cast<void **>(&spIDispatch)); // Get the IDispatch
if (SUCCEEDED(hr) && spIDispatch)
{
// If _spEventScroll is used instead of spIDispatch, an exception will occurr!!!
hr = _spIEventTarget->addEventListener(_bstr_t("scroll"), spIDispatch, VARIANT_TRUE);
if (SUCCEEDED(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;
}
最后一步是在类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;
}
相关文章:
- 如何创建一个空的全局类并在启动时实例化它
- 即使我读取了所有内容,在FIFO上打开的QSocketNotifier也会一直启动
- 使用 std::string () const 函数启动线程或未来
- 如何修复valgrind启动时的致命错误(与libc6-dbg和libc6-dbg:i386连接)
- 将向量作为类>(值)<向量启动和向量<类>[值]有什么区别
- 如何创建线程序列以按照启动顺序执行任务?
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- 在挂钩启动新线程时解除挂钩进程
- 程序无法启动,因为缺少 libmpc-3.dll
- 从 exe 文件 (Visual Studio ) 启动时调试断言失败
- QSerialPort 在应用程序启动之前正在使用中
- 无法在 Arch Linux 中启动虚幻引擎 4
- C++关于指针和使用函数将它们启动到堆的行为究竟是什么?
- 如何使用 ctypes 停止和重新启动从 Python 运行的C++代码
- 程序在使用 system() 启动另一个可执行文件时停止
- Qt 和 Android - 如何使用 Qandroidjniobject 启动相机
- Q没有管理权限的 exe 无法启动维护工具
- 启动类函数作为失去引用的线程
- 如何使用C++确定应用程序是否已在窗口中启动?
- IE9无法在BHO中的HTMLWindow2上启动onscroll事件