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