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_r("main();"); 

 
    int iRet = A.intVal; 

 
    CString strMsg; 

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

 
    AfxMessageBox(strMsg);

 

 

 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/andrew_85/archive/2010/01/28/5266180.aspx