5

What is the best way to get the return value from IHTMLWindow2::execScript?

I found this link, http://social.msdn.microsoft.com/Forums/en/ieextensiondevelopment/thread/712db8ec-0ceb-4efa-afe3-590dc6bbb7bf, I haven't tried this, is this the right way?

Regards Manoj

2 Answers 2

3

Yes, that's how System.Windows.Forms.HtmlDocument.InvokeScript gets the return value.

Sign up to request clarification or add additional context in comments.

Comments

2

Here's a good article that shows how to do this with C++.

Next is my interpretation of it. Say, if your client-side JavaScript is:

function myMethod(name)
{
    alert("Hello " + name);

    return "Got it!";
}

You can call it as such:

CStringArray arrArgs;
arrArgs.Add(L"John Smith");

CComVariant varRes;
if(CallClientScript(L"myMethod", &arrArgs, &varRes))
{
    if(varRes.vt == VT_BSTR)
        AfxMessageBox(varRes.bstrVal);
}

Where the actual function that interfaces with IHTMLWindow2 is this:

BOOL CallClientScript(LPCTSTR pStrFuncName, CStringArray* pArrFuncArgs, CComVariant* pOutVarRes)
{
    //Call client function in HTML
    //'pStrFuncName' = client script function name
    //'pArrFuncArgs' = if not NULL, list of arguments
    //'pOutVarRes' = if not NULL, will receive the return value
    //RETURN:
    //      = TRUE if done
    BOOL bRes = FALSE;

    CComVariant vaResult;

    CComPtr<IHTMLDocument2> pIDoc2;
    if(SUCCEEDED(this->GetDHtmlDocument(&pIDoc2)))  //Uses CDHtmlDialog as 'this'
    {
        //Getting IDispatch for Java Script objects
        CComPtr<IDispatch> spScript;
        if(SUCCEEDED(pIDoc2->get_Script(&spScript)))
        {
            //Find dispid for given function in the object
            CComBSTR bstrMember(pStrFuncName);
            DISPID dispid = NULL;
            if(SUCCEEDED(spScript->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_USER_DEFAULT, &dispid)))
            {

                const int arraySize = pArrFuncArgs ? pArrFuncArgs->GetSize() : 0;

                //Putting parameters  
                DISPPARAMS dispparams;
                memset(&dispparams, 0, sizeof dispparams);
                dispparams.cArgs      = arraySize;
                dispparams.rgvarg     = new VARIANT[dispparams.cArgs];
                dispparams.cNamedArgs = 0;

                for( int i = 0; i < arraySize; i++)
                {
                    CComBSTR bstr = pArrFuncArgs->GetAt(arraySize - 1 - i); // back reading
                    bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
                    dispparams.rgvarg[i].vt = VT_BSTR;
                }

                EXCEPINFO excepInfo;
                memset(&excepInfo, 0, sizeof excepInfo);
                UINT nArgErr = (UINT)-1;  // initialize to invalid arg

                //Call JavaScript function         
                if(SUCCEEDED(spScript->Invoke(dispid, IID_NULL, 0, DISPATCH_METHOD, &dispparams, &vaResult, &excepInfo, &nArgErr)))
                {
                    //Done!
                    bRes = TRUE;
                }

                //Free mem
                delete [] dispparams.rgvarg;
            }
        }
    }

    if(pOutVarRes)
        *pOutVarRes = vaResult;

    return bRes;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.