程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> IWebbrowser2中C++與JavaScript的交互調用

IWebbrowser2中C++與JavaScript的交互調用

編輯:C++入門知識

IWebbrowser2中C++與JavaScript的交互調用


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 ( dispIdMemberDISPID_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; iInvoke(id, IID_NULL, 0, DISPATCH_METHOD, &dispParams, &vResult, &execInfo, &uArgError);
	delete[] dispParams.rgvarg;
	if ( FAILED(hr) )
		return false;
	return true;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved