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