static void call_event_handlers(HTMLDocumentNode *doc, IHTMLEventObj *event_obj, event_target_t *event_target, ConnectionPointContainer *cp_container, eventid_t eid, IDispatch *this_obj) { handler_vector_t *handler_vector = NULL; int i; HRESULT hres; if(event_target) handler_vector = event_target->event_table[eid]; if(handler_vector && handler_vector->handler_prop) { DISPID named_arg = DISPID_THIS; VARIANTARG arg; DISPPARAMS dp = {&arg, &named_arg, 1, 1}; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = this_obj; TRACE("%s >>>\n", debugstr_w(event_info[eid].name)); hres = call_disp_func(handler_vector->handler_prop, &dp); if(hres == S_OK) TRACE("%s <<<\n", debugstr_w(event_info[eid].name)); else WARN("%s <<< %08x\n", debugstr_w(event_info[eid].name), hres); } if(handler_vector && handler_vector->handler_cnt) { VARIANTARG arg; DISPPARAMS dp = {&arg, NULL, 1, 0}; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = (IDispatch*)event_obj; i = handler_vector->handler_cnt; while(i--) { if(handler_vector->handlers[i]) { TRACE("%s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_disp_func(handler_vector->handlers[i], &dp); if(hres == S_OK) TRACE("%s [%d] <<<\n", debugstr_w(event_info[eid].name), i); else WARN("%s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } } if(cp_container) { ConnectionPoint *cp; if(cp_container->forward_container) cp_container = cp_container->forward_container; for(cp = cp_container->cp_list; cp; cp = cp->next) { if(cp->sinks_size && is_cp_event(cp->data, event_info[eid].dispid)) { for(i=0; i < cp->sinks_size; i++) { if(!cp->sinks[i].disp) continue; TRACE("cp %s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_cp_func(cp->sinks[i].disp, event_info[eid].dispid); if(hres == S_OK) TRACE("cp %s [%d] <<<\n", debugstr_w(event_info[eid].name), i); else WARN("cp %s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } } } }
static void call_event_handlers(HTMLDocumentNode *doc, HTMLEventObj *event_obj, event_target_t *event_target, ConnectionPointContainer *cp_container, eventid_t eid, IDispatch *this_obj) { const BOOL cancelable = event_info[eid].flags & EVENT_CANCELABLE; handler_vector_t *handler_vector = NULL; VARIANT v; HRESULT hres; if(event_target) handler_vector = event_target->event_table[eid]; if(handler_vector && handler_vector->handler_prop) { DISPID named_arg = DISPID_THIS; VARIANTARG arg; DISPPARAMS dp = {&arg, &named_arg, 1, 1}; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = this_obj; V_VT(&v) = VT_EMPTY; TRACE("%s >>>\n", debugstr_w(event_info[eid].name)); hres = call_disp_func(handler_vector->handler_prop, &dp, &v); if(hres == S_OK) { TRACE("%s <<< %s\n", debugstr_w(event_info[eid].name), debugstr_variant(&v)); if(cancelable) { if(V_VT(&v) == VT_BOOL) { if(!V_BOOL(&v)) event_obj->prevent_default = TRUE; }else if(V_VT(&v) != VT_EMPTY) { FIXME("unhandled result %s\n", debugstr_variant(&v)); } } VariantClear(&v); }else { WARN("%s <<< %08x\n", debugstr_w(event_info[eid].name), hres); } } if(handler_vector && handler_vector->handler_cnt) { VARIANTARG arg; DISPPARAMS dp = {&arg, NULL, 1, 0}; int i; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = (IDispatch*)event_obj; i = handler_vector->handler_cnt; while(i--) { if(handler_vector->handlers[i]) { V_VT(&v) = VT_EMPTY; TRACE("%s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_disp_func(handler_vector->handlers[i], &dp, &v); if(hres == S_OK) { TRACE("%s [%d] <<<\n", debugstr_w(event_info[eid].name), i); if(cancelable) { if(V_VT(&v) == VT_BOOL) { if(!V_BOOL(&v)) event_obj->prevent_default = TRUE; }else if(V_VT(&v) != VT_EMPTY) { FIXME("unhandled result %s\n", debugstr_variant(&v)); } } VariantClear(&v); }else { WARN("%s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } } } /* * NOTE: CP events may require doc_obj reference, which we don't own. We make sure that * it's safe to call event handler by checking nsevent_listener, which is NULL for * detached documents. */ if(cp_container && cp_container->forward_container) cp_container = cp_container->forward_container; if(cp_container && cp_container->cps && doc->nsevent_listener) { ConnectionPoint *cp; unsigned i, j; for(j=0; cp_container->cp_entries[j].riid; j++) { cp = cp_container->cps + j; if(!cp->sinks_size || !is_cp_event(cp->data, event_info[eid].dispid)) continue; for(i=0; doc->nsevent_listener && i < cp->sinks_size; i++) { if(!cp->sinks[i].disp) continue; V_VT(&v) = VT_EMPTY; TRACE("cp %s [%u] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_cp_func(cp->sinks[i].disp, event_info[eid].dispid, cp->data->pass_event_arg ? event_obj : NULL, &v); if(hres == S_OK) { TRACE("cp %s [%u] <<<\n", debugstr_w(event_info[eid].name), i); if(cancelable) { if(V_VT(&v) == VT_BOOL) { if(!V_BOOL(&v)) event_obj->prevent_default = TRUE; }else if(V_VT(&v) != VT_EMPTY) { FIXME("unhandled result %s\n", debugstr_variant(&v)); } } VariantClear(&v); }else { WARN("cp %s [%u] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } if(!doc->nsevent_listener) break; } } }
static void call_event_handlers(HTMLDocumentNode *doc, HTMLEventObj *event_obj, event_target_t *event_target, ConnectionPointContainer *cp_container, eventid_t eid, IDispatch *this_obj) { const BOOL cancelable = event_info[eid].flags & EVENT_CANCELABLE; handler_vector_t *handler_vector = NULL; VARIANT v; int i; HRESULT hres; if(event_target) handler_vector = event_target->event_table[eid]; if(handler_vector && handler_vector->handler_prop) { DISPID named_arg = DISPID_THIS; VARIANTARG arg; DISPPARAMS dp = {&arg, &named_arg, 1, 1}; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = this_obj; V_VT(&v) = VT_EMPTY; TRACE("%s >>>\n", debugstr_w(event_info[eid].name)); hres = call_disp_func(handler_vector->handler_prop, &dp, &v); if(hres == S_OK) { TRACE("%s <<< %s\n", debugstr_w(event_info[eid].name), debugstr_variant(&v)); if(cancelable) { if(V_VT(&v) == VT_BOOL) { if(!V_BOOL(&v)) event_obj->prevent_default = TRUE; }else if(V_VT(&v) != VT_EMPTY) { FIXME("unhandled result %s\n", debugstr_variant(&v)); } } VariantClear(&v); }else { WARN("%s <<< %08x\n", debugstr_w(event_info[eid].name), hres); } } if(handler_vector && handler_vector->handler_cnt) { VARIANTARG arg; DISPPARAMS dp = {&arg, NULL, 1, 0}; V_VT(&arg) = VT_DISPATCH; V_DISPATCH(&arg) = (IDispatch*)event_obj; i = handler_vector->handler_cnt; while(i--) { if(handler_vector->handlers[i]) { V_VT(&v) = VT_EMPTY; TRACE("%s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_disp_func(handler_vector->handlers[i], &dp, &v); if(hres == S_OK) { TRACE("%s [%d] <<<\n", debugstr_w(event_info[eid].name), i); if(cancelable) { if(V_VT(&v) == VT_BOOL) { if(!V_BOOL(&v)) event_obj->prevent_default = TRUE; }else if(V_VT(&v) != VT_EMPTY) { FIXME("unhandled result %s\n", debugstr_variant(&v)); } } VariantClear(&v); }else { WARN("%s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } } } if(cp_container) { ConnectionPoint *cp; if(cp_container->forward_container) cp_container = cp_container->forward_container; for(cp = cp_container->cp_list; cp; cp = cp->next) { if(cp->sinks_size && is_cp_event(cp->data, event_info[eid].dispid)) { for(i=0; i < cp->sinks_size; i++) { if(!cp->sinks[i].disp) continue; V_VT(&v) = VT_EMPTY; TRACE("cp %s [%d] >>>\n", debugstr_w(event_info[eid].name), i); hres = call_cp_func(cp->sinks[i].disp, event_info[eid].dispid, &v); if(hres == S_OK) { TRACE("cp %s [%d] <<<\n", debugstr_w(event_info[eid].name), i); if(cancelable) { if(V_VT(&v) == VT_BOOL) { if(!V_BOOL(&v)) event_obj->prevent_default = TRUE; }else if(V_VT(&v) != VT_EMPTY) { FIXME("unhandled result %s\n", debugstr_variant(&v)); } } VariantClear(&v); }else { WARN("cp %s [%d] <<< %08x\n", debugstr_w(event_info[eid].name), i, hres); } } } } } }