1. 程式人生 > >duilib CWebBrowser控制元件 C++呼叫js函式&&js中呼叫C++函式

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" onclick="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" onclick="CallCppFunSub(4,7)">呼叫C++函式</button>  
</body>  
</html> 

C++呼叫javascript請移步這裡:http://blog.csdn.net/sunflover454/article/details/60570940

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