2012-03-02 2 views
1

にHTMLWindow2のonscrollイベントを発生するために失敗した:IE7やIE8を、しかしはドキュメントモードで使用する場合にonscrollイベントを発射するに失敗:IE9を。 onscrollイベントをdocumentElementに登録すると、同じように反応します。IE9は、IEがonscrollイベントを発生することができますBHO

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); 

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() 

その後コンプリートドキュメントウィンドウオブジェクトに助言かなりの間、この問題に取り組んできました。何か案は?本当にありがとう!

答えて

4

IE9とドキュメントモード= IE9では、「新しい」イベントを使用する必要があります。

あなたの派生クラスで今
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; 
} 

最終ステップは、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; 
} 
クラスのQueryInterfaceメソッドに追加することです
関連する問題