因为最近工做须要,查询了一些ActiveX与JavaScript交互方面的资料,现总结以下,但愿对有这方面须要的朋友们有用!呵呵!因为ATL和 COM等相关知识相对比较复杂,本人对此了解比较少,因此在开发时我选择了基于MFC的ActiveX。本文主要讲述了,在ActiveX中多线程操做 时,如何回调JavaScript的方法!其基本原理是,在线程中遇到须要调用JavaScript的方法时,先向ActiveX控件发送消息,而后在 ActiveX控件的消息函数中调用JavaScript的方法,从而实现回调。javascript
程序所实现的功能为,1、页面中经过Javascrpit,调到ActiveX的方法,传入相关参数,由ActiveX完成其它工做。2、页面中经过 Javascrpit,调到ActiveX的方法,获取ActiveX中的处理数据,完成页面数据的显示等操做。3、在ActiveX中建立线程,在线程 中实现回调Javascrpit的方法。java
程序实现以下(VC2005),首先打开VC2005,建立ActiveX控件,多线程
点击“肯定”,而后点击“下一步”,在“控件设置”中,设置以下ide
而后点击完成。函数
打开CECActiveCtrl类,选择重载OnSetClientSite方法,在此方法输入:学习
try
{
if (m_pClientSite)
{
RecreateControlWindow();
}
else
{
DestroyWindow();
}
}
catch(...) {
} 测试
打开文件ECActive.idl,在“调度接口”中添加自定义接口:this
[id(1), helpstring("输入内容")] short SetStr([in] BSTR bstrValue);
[id(2), helpstring("获取进度")] short GetProgrss();
[id(3), helpstring("获取内容")] BSTR GetStr();
[id(4), helpstring("启动线程")] void StarThread();spa
打开文件ECActiveCtrl.h,添加自定义方法:线程
afx_msg short OnSetString(BSTR bstrValue);
afx_msg short OnGetProgrss();
afx_msg BSTR OnGetString();
afx_msg void OnStarThread();
afx_msg LRESULT OnUploadFileProg(WPARAM wParam, LPARAM lParam);
打开文件ECActiveCtrl.cpp,添加
调度映射:
DISP_FUNCTION(CECActiveCtrl, "SetStr", OnSetString, VT_I2, VTS_BSTR)
DISP_FUNCTION(CECActiveCtrl, "GetProgrss", OnGetProgrss, VT_I2, VTS_NONE)
DISP_FUNCTION(CECActiveCtrl, "GetStr", OnGetString, VT_BSTR, VTS_NONE)
DISP_FUNCTION(CECActiveCtrl, "StarThread", OnStarThread, VT_EMPTY, VTS_NONE)
实现方法:
//输入参数
short CECActiveCtrl::OnSetString(BSTR bstrValue)
{
if (NULL != bstrValue)
{
MessageBox(bstrValue, L"提示", 0);
return (short)wcslen(bstrValue);
}
return 0;// (short)wcslen(bstrValue);
}
//回调按钮方法
short CECActiveCtrl::OnGetProgrss()
{
try
{
LPOLECLIENTSITE pClientSite = GetClientSite();
if(pClientSite == NULL) return 0;
IServiceProvider *isp = NULL;
HRESULT hr = pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));
if (FAILED(hr)) return 1;
IServiceProvider *isp2 = NULL;
hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
isp->Release();
if (FAILED(hr)) return 2;
IWebBrowser2* browser = NULL;
hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&browser));
isp2->Release();
if (FAILED(hr)) return 3;
IHTMLDocument* doc = NULL;
hr=browser->get_Document((IDispatch**)&doc);
browser->Release();
if(FAILED(hr)) return 4;
IDispatch* script = NULL;
hr=doc->get_Script(&script);
doc->Release();
if(FAILED(hr)) return 5;
DISPID dispid;
OLECHAR FAR* sHello = L"FileProgress";
hr=script->GetIDsOfNames(IID_NULL,&sHello,1,LOCALE_SYSTEM_DEFAULT,&dispid);
if(FAILED(hr)) return 6;
VARIANTARG varPara[2];
varPara[0].vt = VT_BOOL; //参数2
varPara[0].lVal = TRUE;
varPara[1].vt = VT_I4; //参数1
varPara[1].lVal = 50;
DISPPARAMS dpNoArgs = {varPara, NULL, 2, 0};
//DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};//无参数
CComVariant varDisp;
hr = script->Invoke(dispid,IID_NULL,0,DISPATCH_METHOD,&dpNoArgs,&varDisp,NULL,NULL);
script->Release();
if (FAILED(hr)) return 7;
}
catch(...) {
}
return 50;
}
//获取返回值
BSTR CECActiveCtrl::OnGetString()
{
BSTR bstrVal = L"Wangfeng!";
return bstrVal;
}
//启动线程
void CECActiveCtrl::OnStarThread()
{
DWORD dwID;
m_hThread = CreateThread(NULL,NULL, (LPTHREAD_START_ROUTINE)FileUploadThread, (LPVOID)this, NULL, &dwID);
TRACE("Started the thread %x\n",dwID);
}
//消息函数
LRESULT CECActiveCtrl::OnUploadFileProg(WPARAM wParam, LPARAM lParam)
{
try
{
LPOLECLIENTSITE pClientSite = GetClientSite();
if(pClientSite == NULL) return 0;
IServiceProvider *isp = NULL;
HRESULT hr = pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));
if (FAILED(hr)) return 1;
IServiceProvider *isp2 = NULL;
hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
isp->Release();
if (FAILED(hr)) return 2;
IWebBrowser2* browser = NULL;
hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&browser));
isp2->Release();
if (FAILED(hr)) return 3;
IHTMLDocument* doc = NULL;
hr=browser->get_Document((IDispatch**)&doc);
browser->Release();
if(FAILED(hr)) return 4;
IDispatch* script = NULL;
hr=doc->get_Script(&script);
doc->Release();
if(FAILED(hr)) return 5;
DISPID dispid;
OLECHAR FAR* sHello = L"FileProgress";
hr=script->GetIDsOfNames(IID_NULL,&sHello,1,LOCALE_SYSTEM_DEFAULT,&dispid);
if(FAILED(hr)) return 6;
VARIANTARG varPara[2];
varPara[0].vt = VT_BOOL; //参数2
varPara[0].lVal = TRUE;
varPara[1].vt = VT_I4; //参数1
varPara[1].lVal = (int)wParam;
DISPPARAMS dpNoArgs = {varPara, NULL, 2, 0};
//DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};//无参数
CComVariant varDisp;
hr = script->Invoke(dispid,IID_NULL,0,DISPATCH_METHOD,&dpNoArgs,&varDisp,NULL,NULL);
script->Release();
if (FAILED(hr)) return 7;
}
catch(...) {
}
return S_OK;
}
网页部分:
<HTML>
<H1> 测试 ActiveX 页面 </H1><p>
<OBJECT ID="ECActive" CLASSID="CLSID:94FD3218-4B05-4385-812B-55C0F46ED606"> </OBJECT>
<script language="javascript">
function SetStr()
{
if(window.ActiveXObject)
{
try
{
var strValue;
strValue=document.form1.text1.value;
<!--alert(strValue);-->
document.getElementById("ECActive").SetStr(strValue);
}
catch(e)
{
alert(e);
}
}
}
function GetStr()
{
if(window.ActiveXObject)
{
try
{
var strValue = document.getElementById("ECActive").GetStr();
alert(strValue);
}
catch(e)
{
alert(e);
}
}
}
function GetProgress()
{
if(window.ActiveXObject)
{
try
{
var varValue;
varValue = document.getElementById("ECActive").GetProgrss();
<!--alert(strValue);-->
}
catch(e)
{
alert(e);
}
}
}
function StarThread()
{
if(window.ActiveXObject)
{
try
{
document.getElementById("ECActive").StarThread();
}
catch(e)
{
alert(e);
}
}
}
</script>
<script language="javascript" type="text/javascript">
var element="|"; //滚动条单元竖线
var elements="|"; //滚动条当前竖线
function FileProgress(nProgress, bSendOK)
{
elements =elements + element; //滚动条当前竖线增长一个滚动条单元竖线
document.loading.bar.value=elements; //设置窗体loading表单中bar元素的当前值
document.loading.percentage.value=nProgress+"%"; //设置窗体loading表单中percentage元素的当前值
}
</script>
<body>
<center>
<form name="form1">
<input type="text" name="text1" size="50"><p>
<input type="button" value="输入参数" onclick="javascript:SetStr()"/>
<input type="button" value="返回结果" onclick="javascript:GetStr()"/>
<input type="button" value="回调我吧" onclick="javascript:GetProgress()"/>
<input type="button" value="启动线程" onclick="javascript:StarThread()"/>
</form>
<form name="loading">
<p align="center">
<input type="text" name="bar" size="100" style="border-style:none; background-color:#D3E8D0; font-weight:bold" />
<input type="text" name="percentage" style="border-style:none; background-color:#FFFFFF; max-width:30px"/>
</p>
</form>
</body>
</HTML>
总结,以上即为代码的主要部分,若有不妥之处、不理解之处,请与本人联系!欢迎与各位共同讨论学习!