static HRESULT STDMETHODCALLTYPE dispatch_Invoke(IDispatch* self, DISPID disp_id, REFIID riid, LCID lcid, WORD flags, DISPPARAMS* params, VARIANT* var_res, EXCEPINFO* except, UINT* arg_err) { html_t* html = MC_HTML_FROM_DISPTACH(self); switch(disp_id) { case DISPID_BEFORENAVIGATE2: { BSTR url = V_BSTR(V_VARIANTREF(¶ms->rgvarg[5])); VARIANT_BOOL* cancel = V_BOOLREF(¶ms->rgvarg[0]); HTML_TRACE("dispatch_Invoke: DISPID_BEFORENAVIGATE2(%S)", url); if(url != NULL && wcsncmp(url, L"app:", 4) == 0) { html_notify_text(html, MC_HN_APPLINK, url); *cancel = VARIANT_TRUE; } break; } #if 0 /* Unfortunately, IE does not send DISPID_DOCUMENTCOMPLETE * when refreshing the page (e.g. from context menu). So we workaround * via DISPID_PROGRESSCHANGE below. */ case DISPID_DOCUMENTCOMPLETE: { BSTR url = V_BSTR(V_VARIANTREF(¶ms->rgvarg[0])); html_notify_text(html, MC_HN_DOCUMENTCOMPLETE, url); break; } #endif case DISPID_PROGRESSCHANGE: { LONG progress_max = V_I4(¶ms->rgvarg[0]); LONG progress = V_I4(¶ms->rgvarg[1]); MC_NMHTMLPROGRESS notify; HTML_TRACE("dispatch_Invoke: DISPID_PROGRESSCHANGE(%ld, %ld)", progress, progress_max); /* Send also notification about the progress */ notify.hdr.hwndFrom = html->win; notify.hdr.idFrom = GetDlgCtrlID(html->win); notify.hdr.code = MC_HN_PROGRESS; notify.lProgress = progress; notify.lProgressMax = progress_max; MC_SEND(html->notify_win, WM_NOTIFY, notify.hdr.idFrom, ¬ify); /* This replaces DISPID_DOCUMENTCOMPLETE above */ if(progress < 0 || progress_max < 0) { IWebBrowser2* browser_iface; HRESULT hr; hr = html->browser_obj->lpVtbl->QueryInterface(html->browser_obj, &IID_IWebBrowser2, (void**)&browser_iface); if(MC_ERR(hr != S_OK || browser_iface == NULL)) { MC_TRACE("dispatch_Invoke(DISPID_PROGRESSCHANGE): " "QueryInterface(IID_IWebBrowser2) failed [0x%lx]", hr); } else { BSTR url = NULL; hr = browser_iface->lpVtbl->get_LocationURL(browser_iface, &url); if(hr == S_OK && url != NULL) { html_notify_text(html, MC_HN_DOCUMENTCOMPLETE, url); html_SysFreeString(url); } browser_iface->lpVtbl->Release(browser_iface); } } break; } case DISPID_STATUSTEXTCHANGE: HTML_TRACE("dispatch_Invoke: DISPID_STATUSTEXTCHANGE"); html_notify_text(html, MC_HN_STATUSTEXT, V_BSTR(¶ms->rgvarg[0])); break; case DISPID_TITLECHANGE: HTML_TRACE("dispatch_Invoke: DISPID_TITLECHANGE"); html_notify_text(html, MC_HN_TITLETEXT, V_BSTR(¶ms->rgvarg[0])); break; case DISPID_COMMANDSTATECHANGE: { LONG cmd = V_I4(¶ms->rgvarg[1]); HTML_TRACE("dispatch_Invoke: DISPID_COMMANDSTATECHANGE"); if(cmd == CSC_NAVIGATEBACK || cmd == CSC_NAVIGATEFORWARD) { MC_NMHTMLHISTORY notify; BOOL enabled = (V_BOOL(¶ms->rgvarg[0]) != VARIANT_FALSE); if(cmd == CSC_NAVIGATEBACK) html->can_back = enabled; else html->can_forward = enabled; notify.hdr.hwndFrom = html->win; notify.hdr.idFrom = GetDlgCtrlID(html->win); notify.hdr.code = MC_HN_HISTORY; notify.bCanBack = html->can_back; notify.bCanForward = html->can_forward; MC_SEND(html->notify_win, WM_NOTIFY, notify.hdr.idFrom, ¬ify); } break; } case DISPID_NEWWINDOW2: /* This is called instead of DISPID_NEWWINDOW3 on Windows XP SP2 * and older. */ { VARIANT_BOOL* cancel = V_BOOLREF(¶ms->rgvarg[0]); HTML_TRACE("dispatch_Invoke: DISPID_NEWWINDOW2"); if(html_notify_text(html, MC_HN_NEWWINDOW, L"") == 0) { *cancel = VARIANT_TRUE; HTML_TRACE("dispatch_Invoke(DISPID_NEWWINDOW2): Canceled."); } break; } case DISPID_NEWWINDOW3: { BSTR url = V_BSTR(¶ms->rgvarg[0]); VARIANT_BOOL* cancel = V_BOOLREF(¶ms->rgvarg[3]); HTML_TRACE("dispatch_Invoke: DISPID_NEWWINDOW3"); if(html_notify_text(html, MC_HN_NEWWINDOW, url) == 0) { *cancel = VARIANT_TRUE; HTML_TRACE("dispatch_Invoke(DISPID_NEWWINDOW3, '%S'): Canceled.", url); } break; } default: HTML_TRACE("dispatch_Invoke: unsupported disp_id %d", disp_id); return DISP_E_MEMBERNOTFOUND; } return S_OK; }
static ULONG STDMETHODCALLTYPE dispatch_Release(IDispatch* self) { HTML_TRACE("dispatch_Release"); return html_Release(MC_HTML_FROM_DISPTACH(self)); }
static HRESULT STDMETHODCALLTYPE dispatch_QueryInterface(IDispatch* self, REFIID riid, void** obj) { return html_QueryInterface(MC_HTML_FROM_DISPTACH(self), riid, obj); }
static ULONG STDMETHODCALLTYPE dispatch_AddRef(IDispatch* self) { HTML_TRACE("dispatch_AddRef"); return html_AddRef(MC_HTML_FROM_DISPTACH(self)); }