由于最近工作需要,查询了一些ActiveX与JavaScript交互方面的资料,现总结如下,希望对有这方面需要的朋友们有用!呵呵!由于ATL和 COM等相关知识相对比较复杂,本人对此了解比较少,所以在开发时我选择了基于MFC的ActiveX。本文主要讲述了,在ActiveX中多线程操作 时,如何回调JavaScript的方法!其基本原理是,在线程中遇到需要调用JavaScript的方法时,先向ActiveX控件发送消息,然后在 ActiveX控件的消息函数中调用JavaScript的方法,从而实现回调。

      程序所实现的功能为,一、页面中通过Javascrpit,调到ActiveX的方法,传入相关参数,由ActiveX完成其它工作。二、页面中通过 Javascrpit,调到ActiveX的方法,获取ActiveX中的处理数据,完成页面数据的显示等操作。三、在ActiveX中创建线程,在线程 中实现回调Javascrpit的方法。

      程序实现如下(VC2005),首先打开VC2005,创建ActiveX控件,

ActiveX与JavaScript交互,回调等~_第1张图片

点击“确定”,然后点击“下一步”,在“控件设置”中,设置如下

ActiveX与JavaScript交互,回调等~_第2张图片

然后点击完成。

打开CECActiveCtrl类,选择重载OnSetClientSite方法,在此方法输入:

try 
{    
if (m_pClientSite)
{
RecreateControlWindow();
}
else
{
DestroyWindow();
}

catch(...) {
}   

打开文件ECActive.idl,在“调度接口”中添加自定义接口:

    [id(1), helpstring("输入内容")] short SetStr([in] BSTR bstrValue);
[id(2), helpstring("获取进度")] short GetProgrss();
[id(3), helpstring("获取内容")] BSTR GetStr();
[id(4), helpstring("启动线程")] void StarThread();

打开文件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(&isp));    
if (FAILED(hr)) return 1;    
IServiceProvider *isp2 = NULL;    
hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast(&isp2));    
isp->Release();    
if (FAILED(hr)) return 2;    
IWebBrowser2* browser = NULL;    
hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast(&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(&isp));    
if (FAILED(hr)) return 1;    
IServiceProvider *isp2 = NULL;    
hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast(&isp2));    
isp->Release();    
if (FAILED(hr)) return 2;    
IWebBrowser2* browser = NULL;    
hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast(&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;
}

 

网页部分:


测试 ActiveX 页面











 

 
 
 


      总结,以上即为代码的主要部分,如有不妥之处、不理解之处,请与本人联系!欢迎与各位共同讨论学习!