예제 #1
0
    VARIANT ExecuteScript(IWebBrowser2 *pWebBrowser, const SStringW & fun,SArray<SStringW> & params)
    {
        VARIANT varErr;
        VariantInit( &varErr );

        //get document dispatch interface
        IDispatch* pDisp = NULL;

        HRESULT hr = pWebBrowser->get_Document( &pDisp );

        if ( FAILED( hr ) || pDisp == NULL )
        {
            return varErr;
        }

        IHTMLDocument2* pDoc = NULL;
        pDisp->QueryInterface( IID_IHTMLDocument2,(void**)&pDoc );
        pDisp->Release();

        IDispatch* pScript = NULL;
        hr = pDoc->get_Script( &pScript );
        pDoc->Release();

        if ( FAILED( hr ) || pScript == NULL )
        {
            return varErr;
        }

        sbstr bstrMember((int)fun.GetLength(),fun );
        DISPID dispid = 0;
        BSTR bstr = (BSTR)bstrMember;
        hr = pScript->GetIDsOfNames( IID_NULL,&(bstr),1,LOCALE_SYSTEM_DEFAULT,&dispid );

        if ( FAILED( hr ) )
        {
            return varErr;
        }

        DISPPARAMS dispparams;
        ::ZeroMemory( &dispparams,sizeof( DISPPARAMS ) );
        dispparams.cArgs = (UINT)params.GetCount();
        dispparams.rgvarg = new VARIANT[dispparams.cArgs];
        dispparams.cNamedArgs = 0;

        for ( size_t i = 0;i < params.GetCount();i++ )
        {
            size_t indx = params.GetCount() - i - 1;
            sbstr bstrParam((int)params[indx].GetLength(),params[indx]);
            dispparams.rgvarg[i].bstrVal = bstrParam.Release();
            dispparams.rgvarg[i].vt = VT_BSTR;
        }

        EXCEPINFO excepinfo;
        ::ZeroMemory( &excepinfo,sizeof( EXCEPINFO ) );
        VARIANT varRet;
        UINT nArgErr = (UINT)-1;	//initialize to invalid arg

        hr = pScript->Invoke( dispid,IID_NULL,0,DISPATCH_METHOD,&dispparams,&varRet,&excepinfo,&nArgErr );

        delete []dispparams.rgvarg;
        pScript->Release();

        if ( FAILED( hr ) )
        {
            return varErr;
        }

        return varRet;
    }
예제 #2
0
// thanks to Eugene Khodakovsky (I've just modified his code to make more lazy script call)
BOOL CHtmlViewer::ExecScript(TCHAR* ScriptContent,VARIANT* pScriptResult,EXCEPINFO* pExcepInfo)
{
    HRESULT hr = S_OK;

    IDispatch* pHtmlDocDispatch = NULL;
    IHTMLDocument2* pHtmlDoc = NULL;
    DISPID dispid = NULL;
    BSTR bstrMember;
    IDispatch* spScript;

    if (IsBadWritePtr(pExcepInfo,sizeof(EXCEPINFO)))
        return FALSE;

    memset(pExcepInfo, 0, sizeof(EXCEPINFO));
    pScriptResult->vt=VT_EMPTY;

    // Retrieve the document object.

    hr = pIWebBrowser->get_Document(&pHtmlDocDispatch);
    if (SUCCEEDED (hr) && (pHtmlDocDispatch != NULL))
    {
        hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2,(void**)&pHtmlDoc);
        if (SUCCEEDED (hr) && (pHtmlDoc != NULL))
        {
            //Getting IDispatch for Java Script objects
            hr = pHtmlDoc->get_Script(&spScript);

            if (SUCCEEDED (hr) && (spScript != NULL))
            {
                bstrMember=SysAllocString(L"eval");// THE trick is here
                if (bstrMember)
                {
                    hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1,LOCALE_SYSTEM_DEFAULT,&dispid);

                    if (SUCCEEDED (hr))
                    {
                        //Putting parameters
                        DISPPARAMS dispparams;
                        memset(&dispparams, 0, sizeof (DISPPARAMS));
                        dispparams.cArgs      = 1;
                        dispparams.rgvarg     = new VARIANT[dispparams.cArgs];
                        dispparams.cNamedArgs = 0;

                        dispparams.rgvarg[0].vt = VT_BSTR;

                        WCHAR* wScriptContent;
#if (defined(UNICODE)||defined(_UNICODE))
                        wScriptContent=ScriptContent;
#else
                        CAnsiUnicodeConvert::AnsiToUnicode(ScriptContent,&wScriptContent);
#endif
                        dispparams.rgvarg[0].bstrVal = SysAllocString(wScriptContent);

#if ((!defined(UNICODE))&& (!defined(_UNICODE)))
                        free(wScriptContent);
#endif
                        /*
                        // code for those who want to do the same thing
                        // using an array of string "const CStringArray& paramArray" as parameter
                        // instead of eval tips
                        
                        const int arraySize = paramArray.GetSize();
                        //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 = paramArray.GetAt(arraySize - 1 - i);
                            // back reading
                            bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
                            dispparams.rgvarg[i].vt = VT_BSTR;
                        }
                        */

                        if (dispparams.rgvarg[0].bstrVal)
                        {
                            UINT nArgErr = (UINT)-1;// initialize to invalid arg
                            //Call JavaScript function
                            hr = spScript->Invoke(dispid,
                                                    IID_NULL,
                                                    0,
                                                    DISPATCH_METHOD,
                                                    &dispparams,
                                                    pScriptResult,
                                                    pExcepInfo,
                                                    &nArgErr);

                            SysFreeString(dispparams.rgvarg[0].bstrVal);
                        }

                        delete [] dispparams.rgvarg;
                    }

                    SysFreeString(bstrMember);
                }
                
            }
            pHtmlDoc->Release();
        }
        pHtmlDocDispatch->Release();
    }

    return SUCCEEDED (hr);
}