一起学libcef--一个应用libcef的简单例子(windows程序)

之前博客《一起学libcef–搭建自己的libcef运行环境(Win32程序,错误C2220解决方案)》讲述了如何在win32程序中搭建libcef的环境,今天就通过一个简单的例子,在windows程序中使用libcef。

现在再重新写一下如何搞?直接在源代码上搞起!

1 打开源码cefclient解决方案

2 确保cefclient例子可以完美运行

3 在cefclient中,除了util.h之外,全部移除

4 manifests 和 resources文件也可以移除(you must remember to remove the additional manifest files from the Visual Studio project file.)

5 libcef_dll_wrapper 是静态链接,所以我们需要更改项目为动态链接。

接下来就要干我们的事儿了:

1 创建一个自己的头文件ExampleCefApp.h, 在这里新建一个类,继承自CefApp:

CefApp 负责所有的工作, 但是这是一个抽象类,需要计数实现

这样, 我们继承自CefApp创建了一个傀儡类,实际上也什么都没做

#include "include/cef_app.h"
class ExampleCefApp : public CefApp
{
   public:
      ExampleCefApp ()
      {
      }
      virtual ~ExampleCefApp ()
      {
      }

   private:
      IMPLEMENT_REFCOUNTING (ExampleCefApp);
};

2创建一个ExampleCefHandler.h文件,这里面实现一个类继承自所有的event handling classes。

#pragma once

#include "include/cef_client.h"
#include "cefclient/util.h"

class ExampleCefHandler : public CefClient,
                          public CefContextMenuHandler,
                          public CefDisplayHandler,
                          public CefDownloadHandler,
                          public CefDragHandler,
                          public CefGeolocationHandler,
                          public CefKeyboardHandler,
                          public CefLifeSpanHandler,
                          public CefLoadHandler,
                          public CefRequestHandler
{
 public:
      ExampleCefHandler();
      virtual ~ExampleCefHandler();
      CefRefPtr<CefBrowser> GetBrowser();

#pragma region CefClient
      // since we are letting the base implementations handle all of the heavy lifting,
      // these functions just return the this pointer
      virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler () OVERRIDE;
      virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler () OVERRIDE;
      virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler () OVERRIDE;
      virtual CefRefPtr<CefDragHandler> GetDragHandler () OVERRIDE;
      virtual CefRefPtr<CefGeolocationHandler> GetGeolocationHandler () OVERRIDE;
      virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler () OVERRIDE;
      virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler () OVERRIDE;
      virtual CefRefPtr<CefLoadHandler> GetLoadHandler () OVERRIDE;
      virtual CefRefPtr<CefRequestHandler> GetRequestHandler () OVERRIDE;
#pragma endregion // CefClient

#pragma region CefDownloadHandler
      // 这个函数为虚函数,我们必须实现它。但是我们什么也没做,所以下载文件的操作不会工作
      virtual void OnBeforeDownload (CefRefPtr<CefBrowser> browser, CefRefPtr<CefDownloadItem> download_item, const CefString& suggested_name, CefRefPtr<CefBeforeDownloadCallback> callback);
#pragma endregion // CefDownloadHandler 

#pragma region CefLifeSpanHandler
      // 缓存一个指向browser的引用
      virtual void OnAfterCreated (CefRefPtr<CefBrowser> browser) OVERRIDE;

      // 释放browser引用
      virtual void OnBeforeClose (CefRefPtr<CefBrowser> browser) OVERRIDE;
#pragma endregion // CefLifeSpanHandler  

 protected:
      // the browser reference
      CefRefPtr<CefBrowser> browser;

      // Include the default reference counting implementation.
      IMPLEMENT_REFCOUNTING (ExampleCefHandler);
      // Include the default locking implementation.
      IMPLEMENT_LOCKING (ExampleCefHandler);
};

3.创建一个源文件 ExampleCefHandler.cc:

#include "cefclient/ExampleCefHandler.h"

// defined in main.cppp
extern void AppQuitMessageLoop ();

ExampleCefHandler::ExampleCefHandler ()
{
}

ExampleCefHandler::~ExampleCefHandler ()
{
}

CefRefPtr<CefBrowser> ExampleCefHandler::GetBrowser ()
{
   return browser;
}

CefRefPtr<CefContextMenuHandler> ExampleCefHandler::GetContextMenuHandler ()
{
   return this;
}

CefRefPtr<CefDisplayHandler> ExampleCefHandler::GetDisplayHandler ()
{
   return this;
}

CefRefPtr<CefDownloadHandler> ExampleCefHandler::GetDownloadHandler ()
{
   return this;
}

CefRefPtr<CefDragHandler> ExampleCefHandler::GetDragHandler ()
{
   return this;
}

CefRefPtr<CefGeolocationHandler> ExampleCefHandler::GetGeolocationHandler ()
{
   return this;
}

CefRefPtr<CefKeyboardHandler> ExampleCefHandler::GetKeyboardHandler ()
{
   return this;
}

CefRefPtr<CefLifeSpanHandler> ExampleCefHandler::GetLifeSpanHandler ()
{
   return this;
}

CefRefPtr<CefLoadHandler> ExampleCefHandler::GetLoadHandler ()
{
   return this;
}

CefRefPtr<CefRequestHandler> ExampleCefHandler::GetRequestHandler ()
{
   return this;
}

void ExampleCefHandler::OnBeforeDownload (CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDownloadItem> download_item,
const CefString& suggested_name, CefRefPtr<CefBeforeDownloadCallback> callback)
{
   UNREFERENCED_PARAMETER (browser);
   UNREFERENCED_PARAMETER (download_item);
   callback->Continue (suggested_name, true);
}

void ExampleCefHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();
  AutoLock lock_scope (this);

  this->browser = browser;

  CefLifeSpanHandler::OnAfterCreated (browser);
}

void ExampleCefHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser)
{
  REQUIRE_UI_THREAD();
  AutoLock lock_scope (this);

  browser = NULL;
  AppQuitMessageLoop();

  CefLifeSpanHandler::OnBeforeClose (browser);
}

4. 最后,创建一个主函数:

#include "cefclient/ExampleCefApp.hpp"
#include "cefclient/ExampleCefHandler.hpp"
#include "cefclient/util.h"
#include <windows.h>

#define BROWSER_WINDOW_CLASS TEXT("BrowserWindowClass")
#define INVALID_HWND (HWND)INVALID_HANDLE_VALUE
#define MESSAGE_WINDOW_CLASS TEXT("MessageWindowClass")
#define QUIT_CEF_EXAMPLE 0xABAD1DEA

namespace
{
   CefRefPtr<ExampleCefHandler> example_cef_handler;
   HWND application_message_window_handle = INVALID_HWND;
}

LRESULT CALLBACK BrowserWindowWndProc (HWND, UINT, WPARAM, LPARAM);
void CreateBrowserWindow (HINSTANCE instance_handle, int show_minimize_or_maximize)
{
   WNDCLASSEX wcex = { 0 };
   wcex.cbSize        = sizeof (wcex);
   wcex.style         = CS_HREDRAW | CS_VREDRAW;
   wcex.lpfnWndProc   = BrowserWindowWndProc;
   wcex.hInstance     = instance_handle;
   wcex.hCursor       = LoadCursor (NULL, IDC_ARROW);
   wcex.hbrBackground = WHITE_BRUSH;
   wcex.lpszClassName = BROWSER_WINDOW_CLASS;
   RegisterClassEx (&wcex);
   HWND window_handle (CreateWindow (BROWSER_WINDOW_CLASS, BROWSER_WINDOW_CLASS,
   WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, 0,
   CW_USEDEFAULT, 0, NULL, NULL, instance_handle, NULL));
   ShowWindow (window_handle, show_minimize_or_maximize);
   UpdateWindow (window_handle);
}

LRESULT CALLBACK MessageWindowWndProc (HWND, UINT, WPARAM, LPARAM);
HWND CreateMessageWindow (HINSTANCE instance_handle)
{
   WNDCLASSEX wcex    = {0};
   wcex.cbSize        = sizeof (wcex);
   wcex.lpfnWndProc   = MessageWindowWndProc;
   wcex.hInstance     = instance_handle;
   wcex.lpszClassName = MESSAGE_WINDOW_CLASS;
   RegisterClassEx (&wcex);
   return CreateWindow (MESSAGE_WINDOW_CLASS, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, instance_handle, 0);
}

// Program entry point function.
int APIENTRY wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
   UNREFERENCED_PARAMETER (hPrevInstance);
   UNREFERENCED_PARAMETER (lpCmdLine);

   int result (0);
   CefMainArgs main_args (hInstance);
   CefRefPtr<ExampleCefApp> app (new ExampleCefApp);

   // CefExecuteProcess returns -1 for the host process
   if (CefExecuteProcess(main_args, app.get()) == -1)
   {
      CefSettings settings;
      settings.multi_threaded_message_loop = true;
      CefInitialize (main_args, settings, app.get ());
      CreateBrowserWindow (hInstance, nCmdShow);
      application_message_window_handle = CreateMessageWindow (hInstance);

      MSG msg;
      while (GetMessage (&msg, NULL, 0, 0))
      {
         TranslateMessage (&msg);
         DispatchMessage (&msg);
      }
      result = static_cast<int>(msg.wParam);

      DestroyWindow (application_message_window_handle);
      application_message_window_handle = INVALID_HWND;

      // disabled due to https://code.google.com/p/chromiumembedded/issues/detail?id=755
      // CefShutdown ();

      UnregisterClass (BROWSER_WINDOW_CLASS, hInstance);
      UnregisterClass (MESSAGE_WINDOW_CLASS, hInstance);
   }
   return result;
}

LRESULT CALLBACK BrowserWindowWndProc (HWND window_handle, UINT message, WPARAM w_param, LPARAM l_param)
{
   LRESULT result (0);
   switch (message)
   {
      case WM_CREATE:
         {
            example_cef_handler = new ExampleCefHandler();

            RECT rect = { 0 };
            GetClientRect (window_handle, &rect);

            CefWindowInfo info;
            info.SetAsChild(window_handle, rect);

            CefBrowserSettings settings;
            CefBrowserHost::CreateBrowser(info, example_cef_handler.get(),
            CefString ("http://www.google.com"), settings, NULL);
         }
         break;

      case WM_SIZE:
         {
            // from the cefclient example, do not allow the window to be resized to 0x0 or the layout will break;
            // also be aware that if the size gets too small, GPU acceleration disables
            if ((w_param != SIZE_MINIMIZED)
             && (example_cef_handler.get ())
             && (example_cef_handler->GetBrowser ()))
            {
               CefWindowHandle hwnd (example_cef_handler->GetBrowser ()->GetHost ()->GetWindowHandle ());
               if (hwnd)
               {
                  RECT rect = { 0 };
                  GetClientRect (window_handle, &rect);
                  HDWP hdwp = BeginDeferWindowPos (1);
                  hdwp = DeferWindowPos (hdwp, hwnd, NULL,rect.left,
                  rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);
                  EndDeferWindowPos (hdwp);
               }
            }
         }
         break;

      case WM_ERASEBKGND:
         {
            if ((example_cef_handler.get ())
             && (example_cef_handler->GetBrowser ()))
            {
               CefWindowHandle hwnd (example_cef_handler->GetBrowser()->GetHost()->GetWindowHandle());
               // from the cefclient example, don‘t erase the background
               // if the browser window has been loaded to avoid flashing
               result = hwnd ? 1 : DefWindowProc (window_handle, message, w_param, l_param);
            }
         }
         break;

      case WM_ENTERMENULOOP:
         {
            if (!w_param)
            {
               CefSetOSModalLoop (true);
            }
            result = DefWindowProc (window_handle, message, w_param, l_param);
         }
         break;

      case WM_EXITMENULOOP:
         {
            if (!w_param)
            {
               CefSetOSModalLoop (false);
            }
            result = DefWindowProc (window_handle, message, w_param, l_param);
         }
         break;

      case WM_DESTROY:
         break;

      default:
         {
            result = DefWindowProc (window_handle, message, w_param, l_param);
         }
         break;
   }
   return result;
}

LRESULT CALLBACK MessageWindowWndProc (HWND window_handle, UINT message, WPARAM w_param, LPARAM l_param)
{
   LRESULT result (0);
   switch (message)
   {
      case WM_COMMAND:
         {
            if (w_param == QUIT_CEF_EXAMPLE)
            {
               PostQuitMessage(0);
            }
         }
         break;

      default:
         {
            result = DefWindowProc (window_handle, message, w_param, l_param);
         }
         break;
   }
   return result;
}

void AppQuitMessageLoop ()
{
   if (application_message_window_handle != INVALID_HWND)
   {
      PostMessage(application_message_window_handle, WM_COMMAND, QUIT_CEF_EXAMPLE, 0);
   }
}
时间: 2024-11-13 01:44:47

一起学libcef--一个应用libcef的简单例子(windows程序)的相关文章

最简单的Windows程序

准备研究一下vmp 保护,从一个最简单的Windows程序入手似乎是个不错的想法. 怎样才最简单呢,只有一个MessageBox 调用好了. 弹出消息,退出,哦也,够简单吧. 祭出法器VC2010,新建win32 项目, #include "stdafx.h" int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR    lpCmdLine, int       nCmdShow) { Me

用R语言实现一个求导的简单例子

在学习导数的时候,老师都会这样解释,假设y=f(x),对点(x0,y0)的求导过程如下:设dx是一个很小的数=> y0+dy=f(x0+dx)=> dy=f(x0+dx)-y0则在这一点的导数a=dy/dx这样假设的前提是dx很小,所以x0至(x0+dx)很短,可以近似为一条直线,则dy/dx可以看成是点(x0,y0)和点(x0+dx,y0+dy)连成直线的斜率因此关于某个点的导数,其意义也可以解释成在该点的变化率 下面用R语言实现一个简单例子:假设:y=1/x,求点(1,1)的导数 x<

Java_Activiti5_菜鸟也来学Activiti5工作流_之入门简单例子(一)

1 // VacationRequest.java 2 3 /** 4 * author : 冯孟活 ^_^ 5 * dates : 2015年9月1日 下午10:32:58 6 * class : 演示简单的公司请假流程 7 * 8 * 一个简单的流程分三个步骤: 9 * 1.发布流程(部署流程定义) 10 * 2.启动流程实例 11 * 3.完成任务(先查询任务,后完成任务) 12 * 4.挂起.激活一个流程实例(可选) 13 */ 14 public class VacationReque

把C#程序(含多个Dll)合并成一个Exe的超简单方法

原文:把C#程序(含多个Dll)合并成一个Exe的超简单方法 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. 但是,很多时候我们本想开发一款只需要一个exe就能完美运行的小工具.那该怎么办呢? 下文介绍一种超简单的方法,不用写一行代码就可轻松实现. 这里我们需要用到一款名为Costura.Fody的工具.Costura.Fody是一个Fody框架下的插件,可通过Nuget安装到VS工程中.安装之后,就可以将项目所依赖的DLL(甚至PDB)文件

如何利用CEF3创建一个简单的应用程序 (Windows Platform)

1. 说明 这篇文章主要讲述如何利用CEF3来创建一个简单的应用程序,引用的是1535及以上版本中包含的 Cefsimple 项目例子.如果想知道关于CEF3更多的使用方法,可以去访问 GeneralUsage. 2. 开始 首先,根据自身所使用的开发平台,可以去 这里 下载对应的发布版本.针对这个教程,我们需要下载1750或者更新的版本.当前支持的平台有Windows, Linux和Mac OS X.每一个版本都包含了当在特定平台上编译特定版本CEF3时所需要的所有文件和资源.您可以通过包含在

通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

实验一:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1 1)实验部分(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用 gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与

实验---反汇编一个简单的C程序(杨光)

反汇编一个简单的C程序 攥写人:杨光  学号:20135233 ( *原创作品转载请注明出处*) ( 学习课程:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ) 实验要求:  实验部分(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用  gcc –S –o main.s main.c -m32 命令编译成汇编代码, 代码如下: int g(int x) { retu

零元学Expression Blend 4 - Chapter 33 简单轻松的学会如何使用Visual States(下)

原文:零元学Expression Blend 4 - Chapter 33 简单轻松的学会如何使用Visual States(下) 上篇提到了Visual State Manager中文翻译为视觉状态管理器是Blend的强大功能之一 本篇要更深入介绍如何使用 ? 上篇提到了Visual State Manager中文翻译为视觉状态管理器是Blend的强大功能之一 本篇要更深入介绍如何使用 ? 本篇范例最後成果: ? 很抱歉,阁下使用的浏览器并不支援 IFrame,不能正常浏览我的网页 ? 01

利用JSP编程技术实现一个简单的购物车程序

实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP中数据库编程方法: 二.实验要求 : 利用JSP编程技术实现一个简单的购物车程序,具体要求如下. (1)用JSP编写一个登录页面,登录信息中有用户名和密码,分别用两个按钮来提交和重置登录信息. (2)编写一个JSP程序来处理用户提交的登录信息,如果用户名为本小组成员的名字且密码为对应的学号时,采用J