VC与JavaScript混合编程2

本文介绍了两种实现VC与JavaScript互相调用的方法:通过使用ATL+IWebBrowser2接口和IDispatch接口+IScriptControl接口。文章详细阐述了如何在VC中调用JavaScript函数及如何在JavaScript中调用VC函数的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有两种方式可以实现:ATL+IWebBrowser2接口和IDispatch接口+IScriptControl接口。

ATL+IWebBrowser2

一、JavaScript调用VC的函数

1.编写Activex控件,在JavaScript中创建控件对象,并调用控件提供的方法

二、VC调用JavaScript的函数

关键是获取IWebBrowser2对象和IHTMLDocument对象及Script接口(IDispatch自动化接口)。

客户站点(m_pClientSite)->ServiceProvider->TopLevelBrowser->WebBrowserApp(IWebBrowser2)->Document(IHTMLDocument)->Script接口->JavaScript函数

1.实现COleContrl子类的虚函数CXXXCtrl::OnSetClientSite

    try {

        LPOLECLIENTSITE pClientSite = GetClientSite();

        if(pClientSite == NULL)

            return;

        IServiceProvider *isp = NULL;

        HRESULT hr = pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast(&isp)); //COM对象指针获取一般利用QueryInterface函数

        if (FAILED(hr)) return;

        IServiceProvider *isp2 = NULL;

        hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast(&isp2));

        isp->Release();

        if (FAILED(hr)) return;

        IWebBrowser2* browser = NULL;

        hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast(&browser));

        isp2->Release();

        if (FAILED(hr)) return;

        IHTMLDocument* doc = NULL;

        hr=browser->get_Document((IDispatch**)&doc);

        browser->Release();

        if(FAILED(hr)) return;

        //        IDispatch* script = NULL;

        hr=doc->get_Script(&g_script);

        //        m_script = &script;

        doc->Release();

        if(FAILED(hr))

        {

            g_script = NULL;

            return;

        }

    }

    catch(...) {

    }

    COleControl::OnSetClientSite();

其中g_script是全局变量(IDispatch*),此处最好做成全局变量,因为随着窗口的弹出和关闭,CXXXCtrl类的对象很有可能会不停的变化,如果是成员变量,则该变量的值很有可能在程序执行过程中被改变。

2.在需要调用JavaScript函数的地方输入如下例所示的代码:

    try

    {

        if( NULL != g_script )

        {

            OLECHAR FAR* sClose = L"SelfClose"; //页面的javascript函数

            DISPID dispid;

            HRESULT hr=g_script->GetIDsOfNames(IID_NULL,&sClose,1,LOCALE_SYSTEM_DEFAULT,&dispid);

            if(FAILED(hr)) return;

            DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};

            g_script->Invoke(dispid,IID_NULL,0,DISPATCH_METHOD,&dpNoArgs,NULL,NULL,NULL);

            g_script->Release();

        }

    }

    catch(...){

    }

IDispatch(Automation技术)+IScriptControl接口

一、JavaScript调用VC的函数

利用Automation技术。从IDispatch派生的类,并实现IDispatch的主要函数,尤其是GetIDsOfNames和Invoke。AppWizard简化了制作过程。

1.利用Automation的AppWizard(exe)。

    在基于对话框的应用程序向导过程的Step 2 of 4中,what other support would you like to include选择Automation

    在基于文档视图的应用程序向导过程的Step 3 of 6中,what other support would you like to include选择Automation,在Step 4 of 6中,单击"Advanced"按钮,在File type ID 中输入该自动化组件的名字,也就是javascript中的new ActivexObject(File type ID);中的参数。

2.添加方法和属性

利用类向导,其中Class name选择CXXXAutoProxy,添加函数和属性,与Activex类似

3.在JavaScript中:

3.1 创建组件对象 var obj = new ActiveXObject("JSCallVC.Application");    //JSCallVC.Application为组件对象名,基于对话框的应用程序可以从CXXXAutoProxy实现文件,一般为DlgProxy.cpp,中找到IMPLEMENT_OLECREATE2,其第二个参数即为组件对象名。

3.2 利用组件对象obj调用VC提供的方法和属性如obj.AddTow(4,5);

二、VC调用JavaScript的函数

利用IScriptControlPtr接口(IDispatch)执行JavaScript函数,具体过程如下:

1.include控件msscript.ocx:

    #import "C:/windows/system32/msscript.ocx" // msscript.ocx

    using namespace MSScriptControl;

2.在需要调用JavaScript函数的地方输入如下例所示的代码,注意:JavaScript函数中不能有跟网页有关的函数,如alert——window.alert

    HRESULT hr = CoInitialize(NULL);

    IScriptControlPtr pScriptControl(__uuidof(ScriptControl));

    pScriptControl->Language = "JavaScript";

    pScriptControl->AllowUI = TRUE;    //很重要

 

    //{{将整个文件的内容付给strCode,即AddCode函数的参数

    CStdioFile jsReader;

    jsReader.Open("Test.js",CFile::modeRead);

    CString strCode = "";

    CString strTmp = "";

    while(jsReader.ReadString(strTmp))

    {

        strCode += strTmp;

    }

    //}}将整个文件的内容付给strCode,即AddCode函数的参数

    

    pScriptControl->AddCode((LPTSTR)(LPCTSTR)strCode);

    VARIANT A = pScriptControl->Eval("main();");

    int iRet = A.intVal;

    CString strMsg;

    strMsg.Format("%d",iRet);

    AfxMessageBox(strMsg);

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值