Con risposta BHO IE 9 AddEventListener

  • lunedì 5 marzo 2012 17:31
     
      Contiene codice

    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.

Tutte le risposte

  • mercoledì 7 marzo 2012 07:41
    Moderatore
     
     

    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

  • mercoledì 7 marzo 2012 10:57
     
      Contiene codice

    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.




  • giovedì 8 marzo 2012 15:13
     
     Con risposta

    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.

    • Contrassegnato come risposta jaugusto.pt giovedì 8 marzo 2012 15:13
    •