IWebbrowser2中C++与JavaScript的交互调用

2015-07-20 17:09:13 ? 作者: ? 浏览: 2

JS调用C++

IWebbrowser2中C++与JS交互主要处理IDispatch中的两个接口


1、GetIDsOfNames

这里主要是把需要调用JS函数给编一个号,为什么函数要编号呢?建议看看COM的原理,大概是C++实现的COM调用机制主要是用的虚函数表,但是其他的脚本语言中并没有这个玩意,其他脚本需要调用函数时,只能通过函数的ID来找到对应的函数。


那么我们就来给我们需要的函数一一编号:

函数列表的声明部分

struct _JS_FUNCTION
{
	LPCTSTR	lpName;
	DISPID	id;
	UINT	nArgcCount;
	HRESULT (CMyWebEventHandler::*FUN)(DISPID, DISPPARAMS*, VARIANT*);
};
const _JS_FUNCTION funs[]=
{	
	{ L"setAppState", DISPID_BASE+0, 4, &CMyWebEventHandler::OnGetAppState },
	{ L"OneClickInstall", DISPID_BASE+1, 5, &CMyWebEventHandler::OnOneClickInstall },
//	{ L"GetInstallState", DISPID_BASE+2, 1, &CMyWebEventHandler::OnGetInstallState },
	{ L"DownLoadFile", DISPID_BASE+2, 5, &CMyWebEventHandler::OnDownLoadFile },
	{ L"OpenSite", DISPID_BASE+3, 1, &CMyWebEventHandler::OnOpenSite },
};

根据函数名称对比,在我们的列表中的函数就给其编号

STDMETHODIMP CMyWebEventHandler::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
	if(cNames == 0 || rgszNames == NULL || rgszNames[0] == NULL || rgDispId == NULL)
	{
		return E_INVALIDARG;
	}
	for(int i = 0; i 
  
   

2、Invoke

函数的调用过程发生在这里。


这个接口传来函数的调用的标识是函数ID,那么只要是我们上面标识了的ID,我们就根据其中记录的回调地址调用它的处理函数

STDMETHODIMP CMyWebEventHandler::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid,WORD wFlags, DISPPARAMS* pDispParams,VARIANT* pVarResult, EXCEPINFO* pExcepInfo,UINT* puArgErr )
{
	if ( dispIdMember
    
     DISPID_BASE+4 )
		return E_NOTIMPL;
	if ( pDispParams->cArgs!=funs[dispIdMember-DISPID_BASE].nArgcCount )
		return E_INVALIDARG;
	for(UINT i = 0; i < pDispParams->cArgs; ++i)
	{
		if((pDispParams->rgvarg[i].vt & VT_BSTR) == 0)
		{
			return E_INVALIDARG;
		}
	}
	return (this->*(funs[dispIdMember-DISPID_BASE].FUN))(dispIdMember, pDispParams, pVarResult);
}
    

另外IE里的JS函数一定要写在window.external上面。

所以,需要返回对应的 this指针

HRESULT STDMETHODCALLTYPE CMyWebEventHandler::GetExternal( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch )
{
	*ppDispatch=this;
	return S_OK;
}

C++调用JS


首先是获取函数对应的ID,然后还是Invoke传入函数ID和对应的参数信息

bool ExecJsFun( const wstring& lpJsFun, const vector
    
     & params )
{
	if ( NULL == m_pWebBrowser2 )
		return false;
	CComPtr
     
       pDoc; HRESULT hr = m_pWebBrowser2->get_Document(&pDoc); if ( FAILED(hr) ) return false; CComQIPtr
      
        pDoc2=pDoc; if ( NULL == pDoc2 ) return false; CComQIPtr
       
         pScript; hr = pDoc2->get_Script(&pScript); if ( FAILED(hr) ) return false; DISPID id = NULL; CComBSTR bstrFun(lpJsFun.c_str()); hr = pScript->GetIDsOfNames(IID_NULL, &bstrFun, 1, LOCALE_SYSTEM_DEFAULT, &id); if ( FAILED(hr) ) return false; DISPPARAMS dispParams; memset(&dispParams, 0, sizeof(DISPPARAMS)); int nParamCount = params.size(); if ( nParamCount > 0 ) { dispParams.cArgs =nParamCount; dispParams.rgvarg =new VARIANT[nParamCount]; for (int i=0; i
        
         Invoke(id, IID_NULL, 0, DISPATCH_METHOD, &dispParams, &vResult, &execInfo, &uArgError); delete[] dispParams.rgvarg; if ( FAILED(hr) ) return false; return true; } 
        
       
      
     
    


-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: