diff --git a/dlls/mshtml/conpoint.c b/dlls/mshtml/conpoint.c index 3d7882738cf..da775adcbe4 100644 --- a/dlls/mshtml/conpoint.c +++ b/dlls/mshtml/conpoint.c @@ -159,6 +159,9 @@ static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown * This->sinks[i].unk = sink; *pdwCookie = i+1; + if(!i && This->data && This->data->on_advise) + This->data->on_advise(This->container->outer, This->data); + return S_OK; } diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 732fd5290f6..54d3ca309e2 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -1466,6 +1466,16 @@ static const IHTMLDocument2Vtbl HTMLDocumentVtbl = { HTMLDocument_createStyleSheet }; +static void HTMLDocument_on_advise(IUnknown *iface, cp_static_data_t *cp) +{ + HTMLDocument *This = HTMLDOC_THIS(iface); + + if(This->window) + update_cp_events(This->window, cp); +} + +#undef HTMLDOC_THIS + #define SUPPINFO_THIS(iface) DEFINE_THIS(HTMLDocument, SupportErrorInfo, iface) static HRESULT WINAPI SupportErrorInfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **ppv) @@ -1772,7 +1782,7 @@ static BOOL htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv) return TRUE; } -static cp_static_data_t HTMLDocumentEvents_data = { HTMLDocumentEvents_tid }; +static cp_static_data_t HTMLDocumentEvents_data = { HTMLDocumentEvents_tid, HTMLDocument_on_advise }; static void init_doc(HTMLDocument *doc, IUnknown *unk_impl, IDispatchEx *dispex) { diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 9b01f2648a3..2e2f1c95fba 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -782,13 +782,11 @@ static HRESULT call_cp_func(IDispatch *disp, DISPID dispid) return hres; } -static BOOL is_cp_event(ConnectionPoint *cp, DISPID dispid) +static BOOL is_cp_event(cp_static_data_t *data, DISPID dispid) { - cp_static_data_t *data; int min, max, i; HRESULT hres; - data = cp->data; if(!data) return FALSE; @@ -866,7 +864,7 @@ static void call_event_handlers(HTMLDocumentNode *doc, IHTMLEventObj *event_obj, cp_container = cp_container->forward_container; for(cp = cp_container->cp_list; cp; cp = cp->next) { - if(cp->sinks_size && is_cp_event(cp, event_info[eid].dispid)) { + if(cp->sinks_size && is_cp_event(cp->data, event_info[eid].dispid)) { for(i=0; i < cp->sinks_size; i++) { TRACE("cp %s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_cp_func(cp->sinks[i].disp, event_info[eid].dispid); @@ -1019,6 +1017,25 @@ static BOOL alloc_handler_vector(event_target_t *event_target, eventid_t eid, in return TRUE; } +static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, eventid_t eid) +{ + if(!doc->nsdoc || !(event_info[eid].flags & EVENT_DEFAULTLISTENER)) + return S_OK; + + if(!doc->event_vector) { + doc->event_vector = heap_alloc_zero(EVENTID_LAST*sizeof(BOOL)); + if(!doc->event_vector) + return E_OUTOFMEMORY; + } + + if(!doc->event_vector[eid]) { + doc->event_vector[eid] = TRUE; + add_nsevent_listener(doc, event_info[eid].name); + } + + return S_OK; +} + static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDocumentNode *doc, eventid_t eid, IDispatch *disp) { @@ -1039,20 +1056,7 @@ static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDoc return S_OK; IDispatch_AddRef(disp); - if(doc->nsdoc && (event_info[eid].flags & EVENT_DEFAULTLISTENER)) { - if(!doc->event_vector) { - doc->event_vector = heap_alloc_zero(EVENTID_LAST*sizeof(BOOL)); - if(!doc->event_vector) - return E_OUTOFMEMORY; - } - - if(!doc->event_vector[eid]) { - doc->event_vector[eid] = TRUE; - add_nsevent_listener(doc, event_info[eid].name); - } - } - - return S_OK; + return ensure_nsevent_handler(doc, eid); } HRESULT set_event_handler(event_target_t **event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var) @@ -1123,6 +1127,16 @@ HRESULT attach_event(event_target_t **event_target_ptr, HTMLDocument *doc, BSTR return S_OK; } +void update_cp_events(HTMLWindow *window, cp_static_data_t *cp) +{ + int i; + + for(i=0; i < EVENTID_LAST; i++) { + if((event_info[i].flags & EVENT_DEFAULTLISTENER) && is_cp_event(cp, event_info[i].dispid)) + ensure_nsevent_handler(window->doc, i); + } +} + void check_event_attr(HTMLDocumentNode *doc, nsIDOMElement *nselem) { const PRUnichar *attr_value; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 5de023d0758..a0fb198189c 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -48,6 +48,7 @@ HRESULT get_event_handler(event_target_t**,eventid_t,VARIANT*); HRESULT attach_event(event_target_t**,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*); HRESULT dispatch_event(HTMLDOMNode*,const WCHAR*,VARIANT*,VARIANT_BOOL*); HRESULT call_event(HTMLDOMNode*,eventid_t); +void update_cp_events(HTMLWindow*,cp_static_data_t*); static inline event_target_t **get_node_event_target(HTMLDOMNode *node) { diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 2df6a45f4c0..81cb3c84e22 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -269,8 +269,9 @@ typedef enum { EDITMODE } USERMODE; -typedef struct { +typedef struct _cp_static_data_t { tid_t tid; + void (*on_advise)(IUnknown*,struct _cp_static_data_t*); DWORD id_cnt; DISPID *ids; } cp_static_data_t;