一步步CEF(3)之JavaScript与C++互动

随便先提提,cefclient默认编译就是标准的浏览器。

 

如果不希望看到按钮和url输入框的话,那就将“window_config.with_controls = false;”就可以去掉,不过弹窗的时候还是会有,要在另外的地方修改,类似的地方自行去找。

如果要实现离屏(OSR),不用改太多,只需要改一下:


		CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
		command_line->InitFromString(::GetCommandLineW());
		command_line->AppendSwitch(switches::kOffScreenRenderingEnabled);
		command_line->AppendSwitchWithValue(switches::kOffScreenFrameRate, "30");
		command_line->AppendSwitch(switches::kTransparentPaintingEnabled);

JavaScript和C++交互:

C++调用JavaScript比较简单:

CefRefPtr<CefBrowser> browser = rootWin->GetBrowser();
CefRefPtr<CefFrame> frame = rootWin->GetBrowser()->GetMainFrame();
frame->ExecuteJavaScript(“alert('haha')”, frame->GetURL(), 0);

如果要回调的话,要用window.cefQuery();

frame->ExecuteJavaScript("window.cefQuery({request: 'mssage aaa',onSuccess: function(response) {target.innerText = response;},onFailure: function(error_code, error_message) {}});;", frame->GetURL(), 0);

这个还没完。还要将下面这个class添加到MessageHandler里面。


namespace client {

	class MsgHandler : public CefMessageRouterBrowserSide::Handler {
	public:
		typedef cef_termination_status_t TerminationStatus;
		MsgHandler() { CEF_REQUIRE_UI_THREAD(); }

		// Called due to cefQuery execution.
		virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
			CefRefPtr<CefFrame> frame,
			int64 query_id,
			const CefString& request,
			bool persistent,
			CefRefPtr<Callback> callback) OVERRIDE
		{
			const std::string& request_str = request;

			if (request_str.size() == 0)
			{
				return false;
			}
			//...
			callback->Success(CefString());
			return true;

		}
	};

}

有很多人不知道要在哪里添加MessageHandler,打开client_handler.cc,搜索“ClientHandler::OnAfterCreated”。


void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  CEF_REQUIRE_UI_THREAD();

  browser_count_++;
  if (!message_router_) {
	  // Create the browser-side router for query handling.
	  CefMessageRouterConfig config;
	  message_router_ = CefMessageRouterBrowserSide::Create(config);
    // Register handlers with the router.
    test_runner::CreateMessageHandlers(message_handler_set_);
	
	MsgHandler *msgHandler = new MsgHandler();
	message_handler_set_.insert(msgHandler);

	MessageHandlerSet::const_iterator it = message_handler_set_.begin();
	for (; it != message_handler_set_.end(); ++it)
	{
		message_router_->AddHandler(*(it), false);
	}

  }
  // Disable mouse cursor change if requested via the command-line flag.
  if (mouse_cursor_change_disabled_)
    browser->GetHost()->SetMouseCursorChangeDisabled(true);

  if (browser->GetHost()->GetExtension()) {
    // Browsers hosting extension apps should auto-resize.
    browser->GetHost()->SetAutoResizeEnabled(true, CefSize(20, 20),
                                             CefSize(1000, 1000));

    CefRefPtr<CefExtension> extension = browser->GetHost()->GetExtension();
    if (extension_util::IsInternalExtension(extension->GetPath())) {
      // Register the internal handler for extension resources.
      extension_util::AddInternalExtensionToResourceManager(extension,
                                                            resource_manager_);
    }
  }

  NotifyBrowserCreated(browser);
}

这些可能在其他地方也可以搜到类似的做法,但是,如果subProcess.exe没有处理好的话,也不可能收到消息的。在前面我已经发出来了,CefExecuteProcess必须要有app这个参数。重新贴一下代码:


	int SubProcess(HINSTANCE hInstance, int nCmdShow)
	{
		CefMainArgs main_args(hInstance);
		// Parse command-line arguments.
		CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
		command_line->InitFromString(::GetCommandLineW());

		CefRefPtr<CefApp> app;
		ClientApp::ProcessType process_type = ClientApp::GetProcessType(command_line);
		//ClientApp::ProcessType process_type = ClientApp::BrowserProcess;
		//ClientApp::ProcessType process_type = ClientApp::RendererProcess;
		if (process_type == ClientApp::BrowserProcess)
			app = new ClientAppBrowser();
		else if (process_type == ClientApp::RendererProcess)
			app = new ClientAppRenderer();
		else if (process_type == ClientApp::OtherProcess)
			app = new ClientAppOther();
		return CefExecuteProcess(main_args, app, NULL);
	}

我在这个坑踏进了很久没出来,苦涩啊。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: CEF(Chromium Embedded Framework)是一个用于开发嵌入式浏览器的开源框架。CEF 可以在 C++、C#、JavaScript 和 Delphi 等语言中使用,但这里以 C 语言为例。 首先,你需要安装 CEF 的开发包,然后在 C 程序中包含 cef.h 头文件: ```c #include "cef.h" ``` 接下来,需要定义一个 CefApp 类的子类,并实现其中的一些回调函数。这些回调函数可以被 CEF 调用,以响应特定事件,如浏览器初始化、加载页面、接收到 JavaScript 请求等。 ```c class MyCefApp : public CefApp { public: virtual void OnBeforeCommandLineProcessing( const CefString& process_type, CefRefPtr<CefCommandLine> command_line) OVERRIDE { // 在这里可以修改 CEF 的命令行参数 } virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE { return this; } virtual void OnContextInitialized() OVERRIDE { // 在这里可以创建浏览器窗口 } }; ``` 最后,需要调用 CefExecuteProcess() 和 CefInitialize() 函数来初始化 CEF。 ```c int main(int argc, char* argv[]) { CefMainArgs main_args(argc, argv); // 处理 CEF 的命令行参数 CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine(); command_line->InitFromString(::GetCommandLineW()); // 创建 MyCefApp 实例 CefRefPtr<MyCefApp> app(new MyCefApp()); // 初始化 CEF CefInitialize(main_args, *command_line, app.get(), NULL); // 运行 CEF ### 回答2: CEF(Chromium Embedded Framework)是一款基于谷歌开源的Chromium项目的嵌入式浏览器框架。用C语言编写CEF的样例可以按照以下步骤进行: 1. 下载和配置CEF:首先从CEF官方网站(https://cefproject.github.io/)下载适合你的操作系统和编译器的CEF版本,并将其解压到你的项目文件夹中。 2. 创建C文件:在项目文件夹中创建一个新的C文件,例如main.c。 3. 引入CEF库和头文件:在main.c文件中使用#include指令引入CEF库和头文件,以便能够调用CEF的功能和API。 4. 编写CEF初始化代码:在main函数中编写CEF初始化的代码,包括设置CEF的启动参数、初始化CEF框架、创建CEF进程等。 5. 创建CEF窗口:使用CEF的API创建一个新的窗口,并加载指定的URL或本地文件。 6. 处理CEF事件循环:使用CEF的API监听和处理CEF的事件循环,如鼠标点击、键盘输入等。可以编写自定义函数来处理不同的事件。 7. 释放CEF资源:在程序退出前,记得释放CEF的资源,包括关闭CEF窗口、关闭CEF进程等。 以下是一个简单的CEF使用样例: ```c #include <stdio.h> #include <stdlib.h> #include <cef_app.h> #include <cef_browser.h> #include <cef_client.h> int main(int argc, char* argv[]) { CefMainArgs args(argc, argv); CefRefPtr<CefApp> app(new CefAppImpl()); // 初始化CEF框架 int code = CefExecuteProcess(args, app, NULL); if (code >= 0) { return code; } CefSettings settings; // 设置CEF启动参数 CefInitialize(args, settings, app, NULL); // 创建CEF窗口 CefWindowInfo windowInfo; // 设置窗口参数,例如窗口位置、大小等 CefBrowserSettings browserSettings; // 设置浏览器参数,例如是否启用JavaScript、Flash等 CefRefPtr<CefBrowser> browser = CefBrowserHost::CreateBrowserSync(windowInfo, new CefClientImpl(), "https://www.baidu.com", browserSettings, NULL); // 处理CEF事件循环 CefRunMessageLoop(); // 释放CEF资源 browser->GetHost()->CloseBrowser(true); CefShutdown(); return 0; } ``` 上述样例是一个基本的CEF应用程序,它创建一个CEF窗口并加载百度的首页,然后监听和处理CEF的事件循环,最后退出程序时释放CEF的资源。当然,为了更好地理解CEF的使用和功能,你需要深入研究CEF的API文档和示例代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值