天天看点

duilib CWebBrowser控件 C++调用js函数&&js中调用C++函数

C++和js相互调用是个有意思的事情。

一、js中调用C++函数。函数原型

int g_FunSub(int x,int y);
           

调用方式如下:

<html>  
<head>  
    <meta charset="utf-8" />  
    <title></title>  
    <script language="javascript">  
        function CallCppFunSub(x,y)  
        {
			var num = window.external.g_FunSub(x,y); 
			alert(num);
			return num
        } 
		function JsFunSub(x,y)  
        {
			var num = x - y;
			alert(num);
			return num
        }
    </script>  
</head>  
<body>
    <button type="button" οnclick="CallCppFunSub(4,7)">调用C++函数</button>  
</body>  
</html> 
           

具体实现是在C++代码中写的:

#pragma once

class CWebBrowserExUI :
	public CWebBrowserUI
{
public:
	CWebBrowserExUI();
	~CWebBrowserExUI();

	LPCTSTR GetClass() const;
	LPVOID GetInterface(LPCTSTR pstrName);

	virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(__RPC__in REFIID riid, __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, UINT cNames, LCID lcid, __RPC__out_ecount_full(cNames) DISPID *rgDispId);
	virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);

	virtual HRESULT STDMETHODCALLTYPE GetExternal(IDispatch **ppDispatch)
	{
		//重写GetExternal返回一个ClientCall对象
		*ppDispatch = this;
		return S_OK;
	}
};
           
#include "stdafx.h"
#include "WebBrowserExUI.h"
#include <atlcomcli.h>


int g_FunSub(int x, int y)
{
	return (x - y);
}

CWebBrowserExUI::CWebBrowserExUI()
{
}


CWebBrowserExUI::~CWebBrowserExUI()
{
}


LPCTSTR CWebBrowserExUI::GetClass() const
{
	return _T("WebBrowserExUI");
}

LPVOID CWebBrowserExUI::GetInterface(LPCTSTR pstrName)
{
	if (_tcsicmp(pstrName, _T("WebBrowserEx")) == 0)
		return static_cast<CWebBrowserExUI*>(this);

	return CActiveXUI::GetInterface(pstrName);
}


HRESULT CWebBrowserExUI::GetIDsOfNames(const IID& riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
{
	//DISP ID 从200开始
	if (_tcscmp(rgszNames[0], _T("g_FunSub")) == 0)
		*rgDispId = 500;

	return S_OK;
}

HRESULT CWebBrowserExUI::Invoke(DISPID dispIdMember, const IID& riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	//MyOutputDebugStringW(L"%d\n", dispIdMember);
	switch (dispIdMember)
	{
	case 500:
	{
		// 注意参数顺序,反向
		VARIANTARG *varArg = pDispParams->rgvarg;
		int x = _ttoi(static_cast<_bstr_t>(varArg[1]));
		int y = _ttoi(static_cast<_bstr_t>(varArg[0]));
		int n = g_FunSub(x, y);
		*pVarResult = CComVariant(n);
		return S_OK;
	}

	default:
		break;
	}

	return CWebBrowserUI::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
}
           

二、C++调用js方法。

function JsFunSub(x,y)
           

C++中这么调用:

void CMainFrameWnd::OnClick(TNotifyUI& msg)
{
	CDuiString sCtrlName = msg.pSender->GetName();

	if (sCtrlName.CompareNoCase(_T("CallJsBtn")) == 0)
	{
		// C++调用js方法,示例
		// 注意参数顺序,反向
		VARIANT arg[2] = { CComVariant(7),CComVariant(3)};//JsFunSub(3,7)
		VARIANT varRet;
		m_pBrowser->InvokeMethod(m_pBrowser->GetHtmlWindow(),_T("JsFunSub"),&varRet,arg,2);
		int nResult =  varRet.intVal;//-4
		return;
	}


	WindowImplBase::OnClick(msg);
}
           

js中这样实现:

<html>  
<head>  
    <meta charset="utf-8" />  
    <title></title>  
    <script language="javascript">  
        function CallCppFunSub(x,y)  
        {
			var num = window.external.g_FunSub(x,y); 
			alert(num);
			return num
        } 
		function JsFunSub(x,y)  
        {
			var num = x - y;
			alert(num);
			return num
        }
    </script>  
</head>  
<body>
    <button type="button" οnclick="CallCppFunSub(4,7)">调用C++函数</button>  
</body>  
</html> 
           

C++调用javascript请移步这里: http://blog.csdn.net/sunflover454/article/details/60570940

示例工程下载地址(VS2013):

http://download.csdn.net/detail/sunflover454/9774299

继续阅读