ActiveX中调用JavaScript

利用IWebBrowser2和IHTMLDocument2这两个COM组件来访问包含ActiveX控件的外部Web页面上的所有元素。具体实现步骤如下:
1, 在CMyActiveXCtrl类中加入两个变量:
IWebBrowser2* pWebBrowser; //IE浏览器
IHTMLDocument2* pHTMLDocument; //包含此控件的web页面
2,重载OnSetClientSite函数。
{
    HRESULT hr = S_OK;
    IServiceProvider *isp, *isp2 = NULL;
    if (!m_pClientSite)
    {
        COMRELEASE(pWebBrowser);
    }
    else
    {
        hr = m_pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(%26amp;isp));
        if (FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }
        hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider,   reinterpret_cast<void **>(%26amp;isp2));
        if (FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }
        hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2,              reinterpret_cast<void **>(%26amp;pWebBrowser)); //查询IE浏览器接口
        if (FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }
        hr = pWebBrowser->get_Document((IDispatch**)%26amp;pHTMLDocument); //查询Web页面接口
        if(FAILED(hr))
        {
            hr = S_OK;
            goto cleanup;
        }
        cleanup:
        // Free resources.
        COMRELEASE(isp);
        COMRELEASE(isp2);
    }
}
3,控件在加载后会调用OnSetClientSite函数的,因此就会查询到对应包含控件的Web页面,有了这个页面后,就可以使用下述函数来调用Web页面中的JavaScript函数了。下述代码来自CodeGuru 的文章《JavaScript Calls from C++》,感兴趣的话可以细读。

bool CMyActiveXCtrl::GetJScripts(CComPtr<IHTMLElementCollection>%26amp; spColl)
{
    CHECK_POINTER(pHTMLDocument);
    HRESULT hr = pHTMLDocument->get_scripts(%26amp;spColl);
    ATLASSERT(SUCCEEDED(hr));
    return SUCCEEDED(hr);
}

bool CMyActiveXCtrl::CallJScript(const CString strFunc,CComVariant* pVarResult)
{
    CStringArray paramArray;
    return CallJScript(strFunc,paramArray,pVarResult);
}

bool CMyActiveXCtrl::CallJScript(const CString strFunc,const CString strArg1,CComVariant* pVarResult)
{
    CStringArray paramArray;
    paramArray.Add(strArg1);
    return CallJScript(strFunc,paramArray,pVarResult);
}

bool CMyActiveXCtrl::CallJScript(const CString strFunc,const CString strArg1,const CString strArg2,CComVariant* pVarResult)
{
    CStringArray paramArray;
    paramArray.Add(strArg1);
    paramArray.Add(strArg2);
    return CallJScript(strFunc,paramArray,pVarResult);
}

bool CMyActiveXCtrl::CallJScript(const CString strFunc,const CString strArg1,const CString strArg2,const CString strArg3,CComVariant* pVarResult)
{
    CStringArray paramArray;
    paramArray.Add(strArg1);
    paramArray.Add(strArg2);
    paramArray.Add(strArg3);
    return CallJScript(strFunc,paramArray,pVarResult);
}

bool CMyActiveXCtrl::CallJScript(const CString strFunc, const CStringArray%26amp; paramArray,CComVariant* pVarResult)
{
    CComPtr<IDispatch> spScript;
    if(!GetJScript(spScript))
    {
        //ShowError("Cannot GetScript");
        return false;
    }
    CComBSTR bstrMember(strFunc);
    DISPID dispid = NULL;
    HRESULT hr = spScript->GetIDsOfNames(IID_NULL,%26amp;bstrMember,1,
    LOCALE_SYSTEM_DEFAULT,%26amp;dispid);
    if(FAILED(hr))
    {
         //ShowError(GetSystemErrorMessage(hr));
         return false;
    }
    const int arraySize = paramArray.GetSize();
    DISPPARAMS dispparams;
    memset(%26amp;dispparams, 0, sizeof dispparams);
    dispparams.cArgs = arraySize;
    dispparams.rgvarg = new VARIANT[dispparams.cArgs];
    for( int i = 0; i < arraySize; i++)
    {
         CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back reading
         bstr.CopyTo(%26amp;dispparams.rgvarg[i].bstrVal);
         dispparams.rgvarg[i].vt = VT_BSTR;
    }
    dispparams.cNamedArgs = 0;
    EXCEPINFO excepInfo;
    memset(%26amp;excepInfo, 0, sizeof excepInfo);
    CComVariant vaResult;
    UINT nArgErr = (UINT)-1; // initialize to invalid arg
    hr = spScript->Invoke(dispid,IID_NULL,0,
    DISPATCH_METHOD,%26amp;dispparams,%26amp;vaResult,%26amp;excepInfo,%26amp;nArgErr);
    delete [] dispparams.rgvarg;
    if(FAILED(hr))
    {
         //ShowError(GetSystemErrorMessage(hr));
         return false;
    }
    if(pVarResult)
    {
         *pVarResult = vaResult;
    }
    return true;
}
4,现在就可以来测试上述两种调用JavaScript函数的方式了,为了简单起见,就在原文代码的基础上修改了下。
{
     AFX_MANAGE_STATE(AfxGetStaticModuleState());
     m_OutputParameter = m_InputParameter;
     CString strOnLoaded("OnLoaded");
     this->CallJScript(strOnLoaded);
}
并且在web页面中加入了一个测试用的JavaScript函数
{
     alert("test");
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值