If you mean window.postMessage, you'd need to add a listener for message
event on DOM window
object (window.addEventListener("message")
) from your BHO. To get the window
object, use IWebBrowser2::get_Document
, IHTMLDocument2::get_parentWindow
, then query the window
for IEventTarget
and call addEventListener
. Give it an implementation of IDispatch
as listener
parameter. It will be called back as IDispatch::Invoke(DISPID_VALUE)
when a message is posted.
[EDITED] This update is based upon the updated code you posted.
I can't tell why IEventTarget
is still undefined for you (perhaps, there's a problem with your Visual Studio include path configuration). So, just grab the definitions from here:
MIDL_INTERFACE("305104b9-98b5-11cf-bb82-00aa00bdce0b")
IEventTarget : public IDispatch
{
public:
virtual /* [id] */ HRESULT STDMETHODCALLTYPE addEventListener(
/* [in] */ __RPC__in BSTR type,
/* [in] */ __RPC__in_opt IDispatch *listener,
/* [in] */ VARIANT_BOOL useCapture) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE removeEventListener(
/* [in] */ __RPC__in BSTR type,
/* [in] */ __RPC__in_opt IDispatch *listener,
/* [in] */ VARIANT_BOOL useCapture) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE dispatchEvent(
/* [in] */ __RPC__in_opt IDOMEvent *evt,
/* [out][retval] */ __RPC__out VARIANT_BOOL *pfResult) = 0;
};
MIDL_INTERFACE("305104ba-98b5-11cf-bb82-00aa00bdce0b")
IDOMEvent : public IDispatch
{
public:
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_bubbles(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_cancelable(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_currentTarget(
/* [out][retval] */ __RPC__deref_out_opt IEventTarget **p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_defaultPrevented(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_eventPhase(
/* [out][retval] */ __RPC__out USHORT *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_target(
/* [out][retval] */ __RPC__deref_out_opt IEventTarget **p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_timeStamp(
/* [out][retval] */ __RPC__out ULONGLONG *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_type(
/* [out][retval] */ __RPC__deref_out_opt BSTR *p) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE initEvent(
/* [in] */ __RPC__in BSTR eventType,
/* [in] */ VARIANT_BOOL canBubble,
/* [in] */ VARIANT_BOOL cancelable) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE preventDefault( void) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE stopPropagation( void) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE stopImmediatePropagation( void) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_isTrusted(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_cancelBubble(
/* [in] */ VARIANT_BOOL v) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_cancelBubble(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_srcElement(
/* [out][retval] */ __RPC__deref_out_opt IHTMLElement **p) = 0;
};
Next, your CIEUIEventListener
doesn't look a like a COM object implementation. I don't see any IUnknown
and IDispatch
methods, perhaps you just didn't show it. You don't have to derive from IDispatchEx
either, IDispatch
is enough. I suggest you take the following implementation of DOM event sink as a base, it's self-explanatory:
// Usage:
//
// CComPtr<CEventSink> eventSink;
// CEventSink::Create(pTestScript, &eventSink); // pass eventSink where IDispatch* is expected
//
class CEventSink:
public CComObjectRoot,
public IDispatch
{
protected:
CTestScript* m_pParent;
CEventSink() { m_pParent = NULL; }
public:
BEGIN_COM_MAP(CEventSink)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// create and initialize
static HRESULT Create(CTestScript* pParent, CEventSink** pp)
{
CComObject<CEventSink>* pThis = NULL;
CComObject<CEventSink>::CreateInstance(&pThis);
if (!pThis)
return E_OUTOFMEMORY;
pThis->m_pParent = pParent;
(*pp = pThis)->AddRef();
return S_OK;
}
// IDispatch
STDMETHODIMP GetTypeInfoCount(UINT* pctinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
{
return DISP_E_UNKNOWNNAME;
}
STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
if ( dispidMember == DISPID_VALUE )
{
// handle the event
// for example, call some method on m_pParent
}
return DISP_E_MEMBERNOTFOUND;
}
};