CEF3中JS调用C++单进程、多进程讲解

CEF3里JS回调C++有两种模式,1.单进程模式、2.多进程模式

 

 

一、单进程模式

让自己的SimpleApp来继承 CefRenderProcessHandler这个抽象类,然对其下面的纯虚函数进行重写,以达到声明JS函数的作用

simple_app.h:

 

class SimpleApp : public CefApp,
                    public CefBrowserProcessHandler,
        		public CefRenderProcessHandler {

  // CefRenderProcessHandler methods:
  virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler()
	  OVERRIDE {
	  return this;
  }

  virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
	  CefRefPtr<CefFrame> frame,
	  CefRefPtr<CefV8Context> context) OVERRIDE;

simple_app.cc:

#include "simple_V8Handler.h"
void SimpleApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefFrame> frame,
	CefRefPtr<CefV8Context> context)
{
	// The var type can accept all object or variable
	CefRefPtr<CefV8Value> pV8 = context->GetGlobal();

	// bind function 
	CefRefPtr<CSimpleV8Handler> pJsHandler(new CSimpleV8Handler());

	CefRefPtr<CefV8Value> pFunc = CefV8Value::CreateFunction(CefString("ShowJsInfo"), pJsHandler);
	pV8->SetValue(CefString("ShowJsInfo"), pFunc, V8_PROPERTY_ATTRIBUTE_NONE);
}

 

新建simple_V8Handler.cpp和simple_V8Handler.h文件用于处理函数请求调用

 

simple_V8Handler.h:

#pragma once
#include "include/cef_v8.h"

class CSimpleV8Handler : public CefV8Handler
{
public:
	CSimpleV8Handler() {};
	~CSimpleV8Handler() {};

public:
	virtual bool Execute(const CefString& name, CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,
		CefRefPtr<CefV8Value>& retval, CefString& exception) OVERRIDE;

private:
	IMPLEMENT_REFCOUNTING(CSimpleV8Handler);
};

 

simple_V8Handler.cpp:

#include "simple_V8Handler.h"

bool CSimpleV8Handler::Execute(
	const CefString& name,
	CefRefPtr<CefV8Value> object,
	const CefV8ValueList& arguments,
	CefRefPtr<CefV8Value>& retval, //这里是设置JS返回值的地方
	CefString& exception)
{
	if (name == CefString("ShowJsInfo"))
	{
		if (arguments.size() == 1 && arguments[0]->IsString())
		{
			CefString arg = arguments[0]->GetStringValue();
                    
                    //注意要把JS发回来的文本的0xA0(EASCII码的空格'\xa0')替换成0x20(ASCII码的空格'\x20')
			std::wstring strInfo(L"这是 JavaScript 发来的数据:");
			strInfo += arg.ToWString();

			::MessageBoxW(0, strInfo.c_str(), L"C++ 提示框", MB_OK);
                   //设置返回值演示
                   //retval = CefV8Value::CreateInt(1);
			return true;
		}
	}
	return false;
}

 

二、多进程模式

请先完成单进程JS回调代码的书写后,再修改为多进程JS回调。

先介绍一下CEF3多进程的通讯模式

 

SimpleApp类里继承的CefRenderProcessHandler主要负责Render进程,

其中Render进程接收到的消息都会在CefRenderProcessHandler::OnProcessMessageReceived

 

SimpleHandler类里继承的CefClient主要负责Browser进程,

其中Browser进程接收到的消息都会在CefClient::OnProcessMessageReceived

 

修改simple_V8Handler.h:

#pragma once
#include "include/cef_v8.h"

class CSimpleV8Handler : public CefV8Handler
{
public:
	CSimpleV8Handler(CefRefPtr<CefBrowser> browser) //改动构造函数
	{
		m_Browser = browser;
	};
	~CSimpleV8Handler() {};

public:
	virtual bool Execute(const CefString& name,
		CefRefPtr<CefV8Value> object,
		const CefV8ValueList& arguments,
		CefRefPtr<CefV8Value>& retval,
		CefString& exception) OVERRIDE;
	
   //新增一个执行JS的函数
	void Execute(const CefString& name, CefRefPtr<CefListValue> arguments, CefRefPtr <CefValue> & retValue);

private:
	CefRefPtr<CefBrowser> m_Browser; //新增保存CEF3窗口句柄变量
	IMPLEMENT_REFCOUNTING(CSimpleV8Handler);
};

 

修改simple_V8Handler.cpp:

 

#include "simple_V8Handler.h"


bool CSimpleV8Handler::Execute(
	const CefString& name,
	CefRefPtr<CefV8Value> object,
	const CefV8ValueList& arguments,
	CefRefPtr<CefV8Value>& retval,
	CefString& exception)
{

	//将参数列表CefV8ValueList转成CefListValue类型
	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create(name);
	CefRefPtr<CefListValue> args = msg->GetArgumentList();
	for (int i = 0; i < arguments.size(); i++)
	{
		if (arguments[i]->IsBool())
		{
			args->SetBool(i, arguments[i]->GetBoolValue());
		}
		else if (arguments[i]->IsInt())
		{
			args->SetInt(i, arguments[i]->GetIntValue());
		}
		else if (arguments[i]->IsString())
		{
			args->SetString(i, arguments[i]->GetStringValue());
		}
		else if (arguments[i]->IsDouble())
		{
			args->SetDouble(i, arguments[i]->GetDoubleValue());
		}
	}

	//可在Render进程处理的JS函数
	if (name == CefString("ShowJsInfo"))
	{
		if (arguments.size() == 1 && arguments[0]->IsString())
		{
			CefString arg = arguments[0]->GetStringValue();
                    
                    //注意要把JS发回来的文本的0xA0(EASCII码的空格'\xa0')替换成0x20(ASCII码的空格'\x20')
			std::wstring strInfo(L"这是 JavaScript 发来的数据:");
			strInfo += arg.ToWString();

			::MessageBoxW(0, strInfo.c_str(), L"C++ 提示框", MB_OK);
                   //设置返回值演示
                   //retval = CefV8Value::CreateInt(1);
			return true;
		}
	}



	//其余需要在Browser进程处理的JS函数就转发到Browser进程去
	if (CefCurrentlyOn(TID_RENDERER))
	{
		// Execute on the browser process.
		m_Browser->SendProcessMessage(PID_BROWSER, msg); //转发到Browser进程去
		return true;
	}
	return false;
}


void CSimpleV8Handler::Execute(const CefString& name, CefRefPtr<CefListValue> arguments, CefRefPtr <CefValue> & retValue)
{
	//执行需要在Browser进程处理的JS函数
 	if (name == CefString("ShowInBrowserJS"))
	{
		if (arguments->GetSize() == 1)
		{
			CefString arg = arguments->GetString(0);
                    
                    //注意要把JS发回来的文本的0xA0(EASCII码的空格'\xa0')替换成0x20(ASCII码的空格'\x20')
			std::wstring strInfo(L"这是 JavaScript 发来的数据:");
			strInfo += arg.ToWString();

			::MessageBoxW(0, strInfo.c_str(), L"C++ 提示框", MB_OK);
			return true;
		}
	}

}

修改simple_app.cc:

#include "simple_V8Handler.h"
void SimpleApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
	CefRefPtr<CefFrame> frame,
	CefRefPtr<CefV8Context> context)
{
	// The var type can accept all object or variable
	CefRefPtr<CefV8Value> pV8 = context->GetGlobal();

	// bind function 
	CefRefPtr<CSimpleV8Handler> pJsHandler(new CSimpleV8Handler(browser)); //构造函数传参

	CefRefPtr<CefV8Value> pFunc = CefV8Value::CreateFunction(CefString("ShowJsInfo"), pJsHandler);
	pV8->SetValue(CefString("ShowJsInfo"), pFunc, V8_PROPERTY_ATTRIBUTE_NONE);
}

 

修改simple_handler.h:

 

//新增继承虚函数
  virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
	  CefProcessId source_process,
	  CefRefPtr<CefProcessMessage> message) OVERRIDE;

修改simple_handler.cc:

#include "simple_V8Handler.h"
bool SimpleHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
	CefProcessId source_process,
	CefRefPtr<CefProcessMessage> message) 
{

	CEF_REQUIRE_UI_THREAD();

	//Browser进程接收到的消息都会在这里
	// TODO:

	//无用消息
	if (!message->IsValid())
	{
		return false;
	}

	//执行函数
	CefString jsFuncName = message->GetName();
	CefRefPtr<CefListValue> jsFuncArgs = message->GetArgumentList();

	CSimpleV8Handler tempV8(browser);
	CefRefPtr<CefValue> retValue; //返回值,这里只接收 不发回Render进程
	tempV8.Execute(jsFuncName, jsFuncArgs, retValue);

	return false;
}

 

 

 

 

 

 

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值