Beispiel #1
0
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(&params->rgvarg[5]));
            VARIANT_BOOL* cancel = V_BOOLREF(&params->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(&params->rgvarg[0]));
            html_notify_text(html, MC_HN_DOCUMENTCOMPLETE, url);
            break;
        }
#endif

        case DISPID_PROGRESSCHANGE:
        {
            LONG progress_max = V_I4(&params->rgvarg[0]);
            LONG progress = V_I4(&params->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, &notify);

            /* 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(&params->rgvarg[0]));
            break;

        case DISPID_TITLECHANGE:
            HTML_TRACE("dispatch_Invoke: DISPID_TITLECHANGE");
            html_notify_text(html, MC_HN_TITLETEXT, V_BSTR(&params->rgvarg[0]));
            break;

        case DISPID_COMMANDSTATECHANGE:
        {
            LONG cmd = V_I4(&params->rgvarg[1]);
            HTML_TRACE("dispatch_Invoke: DISPID_COMMANDSTATECHANGE");

            if(cmd == CSC_NAVIGATEBACK  ||  cmd == CSC_NAVIGATEFORWARD) {
                MC_NMHTMLHISTORY notify;
                BOOL enabled = (V_BOOL(&params->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, &notify);
            }
            break;
        }

        case DISPID_NEWWINDOW2:
        /* This is called instead of DISPID_NEWWINDOW3 on Windows XP SP2
         * and older. */
        {
            VARIANT_BOOL* cancel = V_BOOLREF(&params->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(&params->rgvarg[0]);
            VARIANT_BOOL* cancel = V_BOOLREF(&params->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;
}
Beispiel #2
0
static ULONG STDMETHODCALLTYPE
dispatch_Release(IDispatch* self)
{
    HTML_TRACE("dispatch_Release");
    return html_Release(MC_HTML_FROM_DISPTACH(self));
}
Beispiel #3
0
static HRESULT STDMETHODCALLTYPE
dispatch_QueryInterface(IDispatch* self, REFIID riid, void** obj)
{
    return html_QueryInterface(MC_HTML_FROM_DISPTACH(self), riid, obj);
}
Beispiel #4
0
static ULONG STDMETHODCALLTYPE
dispatch_AddRef(IDispatch* self)
{
    HTML_TRACE("dispatch_AddRef");
    return html_AddRef(MC_HTML_FROM_DISPTACH(self));
}