Answered BHO IE 9 AddEventListener

  • 2012年3月5日 下午 05:31
     
      包含代碼

    Hi,

    I'm trying to capture MutationEvent, but I'm failing on obtaining the event target.

    I sucessfuly managed to add the listener

    CComPtr<IDocumentEvent> spIDocumentEvent;
    hr = _spDocument->QueryInterface(IID_IDocumentEvent, reinterpret_cast<void **>(&spIDocumentEvent));	
    if (SUCCEEDED(hr) && spIDocumentEvent)
    {
    	CComPtr<IDOMEvent> spIDOMEvent;
    	BSTR bstrType = _bstr_t("MutationEvent");
    	hr = spIDocumentEvent->createEvent(bstrType, reinterpret_cast<IDOMEvent **>(&spIDOMEvent));
    	if (SUCCEEDED(hr) && spIDOMEvent)
    	{						
    		CComPtr<IDOMMutationEvent> spIDOMMutationEvent;
    		hr = spIDOMEvent->QueryInterface(IID_IDOMMutationEvent, reinterpret_cast<void **>(&spIDOMMutationEvent));	
    		if (SUCCEEDED(hr) && spIDOMMutationEvent)
    		{	
    			CComPtr<IHTMLElement> spIBody;
    			hr = _spDocument->get_body(reinterpret_cast<IHTMLElement **>(&spIBody));
    			if (SUCCEEDED(hr) && spIBody)
    			{
    				BSTR bstrEmpty = _bstr_t("");
    				BSTR bstrValue = _bstr_t("DOMNodeInserted");
    				hr = spIDOMMutationEvent->initMutationEvent(bstrValue, 
    					VARIANT_TRUE,
    					VARIANT_FALSE,
    					spIBody,
    					bstrEmpty,
    					bstrEmpty,
    					bstrEmpty,
    					0);
    
    				if (SUCCEEDED(hr))
    				{
    					CComPtr<IEventTarget> spIEventTarget;
    					hr = spIBody->QueryInterface(IID_IEventTarget, reinterpret_cast<void **>(&spIEventTarget));	
    					if (SUCCEEDED(hr) && spIEventTarget)
    					{
    						_pObjDomMutationEvent = new CIEDOMMutationEvent();
    
    						hr = spIEventTarget->addEventListener(bstrValue, _pObjDomMutationEvent,  VARIANT_TRUE);
    						if (SUCCEEDED(hr))
    						{
    						...
    						}
    					}
    				}
    			}
    		}
    	}
    }

    Now the problem is that on my sink object, the invoke get's called when I insert a node, but I'm unable to obtain the Node that was inserted, I thought that it would be on the disparams, but they are always "empty"

    HRESULT STDMETHODCALLTYPE CIEDOMMutationEvent::Invoke(
    	DISPID dispIdMember,
    	REFIID riid,
    	LCID lcid,
    	WORD wFlags,
    	DISPPARAMS *pDispParams,
    	VARIANT *pVarResult,
    	EXCEPINFO *pExcepInfo,
    	UINT *puArgErr)
    {
    	if(dispIdMember == 0)
    	{
    		
    		if(pDispParams->rgvarg && pDispParams->rgvarg->vt == VT_DISPATCH)
    		{
    			....
    		}
    	}
    	
    	return S_OK;
    }

    Thanks in advance.

所有回覆

  • 2012年3月7日 上午 07:41
    版主
     
     

    Hello,

    I think you need to call IDOMMutationEvent::newValue property to get the insert node. Please check this document.
    http://msdn.microsoft.com/en-us/library/ie/ff975906(v=vs.85).aspx

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

  • 2012年3月7日 上午 10:57
     
      包含代碼

    Hi, thanks for your reply.

    Consider this code to Add the Event

    CComPtr<IHTMLElement> spIBody;
    hr = _spDocument->get_body(reinterpret_cast<IHTMLElement **>(&spIBody));
    if (SUCCEEDED(hr) && spIBody)
    {
    	CComPtr<IEventTarget> spIEventTarget;
    	hr = spIBody->QueryInterface(IID_IEventTarget, reinterpret_cast<void **>(&spIEventTarget));	
    	if (SUCCEEDED(hr) && spIEventTarget)
    	{
    		_pObjDomMutationEvent = new CIEDOMMutationEvent(); // This class derives from IDispatch
    
    		hr = spIEventTarget->addEventListener(_bstr_t("DOMNodeInserted"), _pObjDomMutationEvent,  VARIANT_TRUE);
    		if (SUCCEEDED(hr))
    		{
    		...
    		}
    	}
    }

    It sucessfully works and I'm able to capture the event inside the "invoke" method in my class CIEDOMMutationEvent

    HRESULT STDMETHODCALLTYPE CIEDOMMutationEvent::Invoke(
    	DISPID dispIdMember,
    	REFIID riid,
    	LCID lcid,
    	WORD wFlags,
    	DISPPARAMS *pDispParams,
    	VARIANT *pVarResult,
    	EXCEPINFO *pExcepInfo,
    	UINT *puArgErr)
    {
    	if(dispIdMember == 0)
    	{
    		// Event happened
    		...
    	}
    	
    	return S_OK;
    }

    Now my problem is that I have no parameters in the pDispParams, and I believe that according to the msdn I should receive 2 parametes, being one a IDOMEvent.

    Maybe it's my implementation of the IDispatch that's isn't accurate, can you give me a example of a IDispatch that should be used when using the new AddEventListener function.

    Thanks.




  • 2012年3月8日 下午 03:13
     
     已答覆

    Hi,

    I Managed to solve the problem!

    In case someone needs the info, the problem is that you need to create a sinker that derives from IDispatchEx and not from IDispatch.

    And on the InvokeEx you will receive the IDomEvent on the DISPARAMS.

    Despite this fact you still need to pass on the AddEventListener only IDispatch, otherwise you will have a crash.

    So create your sink (that derives from IDispatchEx), query the sink for IDispatch, pass it to the AddEventListener and start working with IE9 and the new Events.

    I really think that msdn should be more accurate.

    Thanks.

    • 已標示為解答 jaugusto.pt 2012年3月8日 下午 03:13
    •