使用Duilib 与Cef 开发 Windows客户端

我们已经在Windows上实现了从零构建一个CEF3项目。现在我们在其基础上实现Duilib图形。

Of Course,你可以理解为 在Duilib的基础上嵌入Cef浏览器。

获取Duilib源码,请到Duilib -Github

关于如何编译Duilib库,请参考资料duilib入门简明教程 -Albert

文件导入

以下以Unicode Debug为例。

将Duilib编译后生成的 DuiLib_ud.lib文件添加到 C:\workspace\cef3\MyCef\lib 文件夹内。

将Duilib源码 include文件夹 添加到 C:\workspace\cef3\MyCef 文件夹内。

Duilib_ud.dll文件添加到解决方案跟目录的Debug文件夹内。

解决方案属性设置

打开解决方案属性页面,选择 VC++目录 → 包含目录 添加../include,如下图:

image.png

修改 simple_app.cc

替换 simple_app.cc 文件中此方法代码(就是删了剩下的,只留了一行)

void SimpleApp::OnContextInitialized() {
  CEF_REQUIRE_UI_THREAD();
}

编写主窗口类

新建类 CMainFrame 。

【MainFrame.h 代码清单】

#pragma once

#ifdef _DEBUG
#   ifdef _UNICODE
#       pragma comment(lib, "DuiLib_ud.lib")
#   else
#       pragma comment(lib, "DuiLib_d.lib")
#   endif
#else
#   ifdef _UNICODE
#       pragma comment(lib, "DuiLib_u.lib")
#   else
#       pragma comment(lib, "DuiLib.lib")
#   endif
#endif

#include <UIlib.h>
using namespace DuiLib;
class CMainFrame :
    public WindowImplBase
{
public:
    CMainFrame();
    ~CMainFrame();
    LPCTSTR GetWindowClassName() const;
    virtual CDuiString GetSkinFile();
    virtual CDuiString GetSkinFolder();
    virtual void InitWindow();
};

【MainFrame.cpp 代码清单】

#include "cefsimple\simple_app.h"
#include "cefsimple\simple_handler.h"
#include "MainFrame.h"

CefRefPtr<SimpleHandler> g_handler(new SimpleHandler());

CMainFrame::CMainFrame()
{
}


CMainFrame::~CMainFrame()
{
}

LPCTSTR CMainFrame::GetWindowClassName() const
{
    return _T("DuilibCef");
}
CDuiString CMainFrame::GetSkinFile()
{
    return _T("skin\\MainWindow.xml");
}

CDuiString CMainFrame::GetSkinFolder()
{
    return _T("");
}

void CMainFrame::InitWindow()
{
    RECT rect;
    GetClientRect(this->m_hWnd, &rect);
    int nCx = GetSystemMetrics(SM_CXFULLSCREEN);
    int nCy = GetSystemMetrics(SM_CYFULLSCREEN);

    RECT rt;
    rt.left = rect.left + 0;
    rt.top = rect.top + 0;

    rt.bottom = rt.top + 600;
    rt.right = rt.left + 800;

    CefBrowserSettings browser_settings;
    CefWindowInfo window_info;
    window_info.SetAsChild(m_hWnd, rt);
    BOOL bSucced = CefBrowserHost::CreateBrowser(window_info
        , g_handler
        , _T("http://www.baidu.com/")
        , browser_settings
        , NULL);
}

修改入口文件

【cefsimple_win.cc 代码清单】

// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#pragma comment(lib, "libcef_dll_wrapper.lib")
#pragma comment(lib, "cef_sandbox.lib")
#pragma comment(lib, "libcef.lib")

#include <windows.h>

#include "cefsimple/simple_app.h"
#include "include/cef_sandbox_win.h"
#include "MainFrame.h"

// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically if using the required compiler version. Pass -DUSE_SANDBOX=OFF
// to the CMake command-line to disable use of the sandbox.
// Uncomment this line to manually enable sandbox support.
// #define CEF_USE_SANDBOX 1

#if defined(CEF_USE_SANDBOX)
// The cef_sandbox.lib static library is currently built with VS2013. It may not
// link successfully with other VS versions.
#pragma comment(lib, "cef_sandbox.lib")
#endif


// Entry point function for all processes.
int APIENTRY wWinMain(HINSTANCE hInstance,
                      HINSTANCE hPrevInstance,
                      LPTSTR    lpCmdLine,
                      int       nCmdShow) {
    /* UNREFERENCED_PARAMETER(hPrevInstance);
     UNREFERENCED_PARAMETER(lpCmdLine);*/
  CPaintManagerUI::SetInstance(hInstance);

#if defined(WIN32) && !defined(UNDER_CE)
  HRESULT Hr = ::CoInitialize(NULL);
#else
  HRESULT Hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
#endif
  if (FAILED(Hr)) return 0;

  // Enable High-DPI support on Windows 7 or newer.
  CefEnableHighDPISupport();

  void* sandbox_info = NULL;

#if defined(CEF_USE_SANDBOX)
  // Manage the life span of the sandbox information object. This is necessary
  // for sandbox support on Windows. See cef_sandbox_win.h for complete details.
  CefScopedSandboxInfo scoped_sandbox;
  sandbox_info = scoped_sandbox.sandbox_info();
#endif

  // Provide CEF with command-line arguments.
  CefMainArgs main_args(hInstance);

  // SimpleApp implements application-level callbacks. It will create the first
  // browser instance in OnContextInitialized() after CEF has initialized.
  CefRefPtr<SimpleApp> app(new SimpleApp);

  // CEF applications have multiple sub-processes (render, plugin, GPU, etc)
  // that share the same executable. This function checks the command-line and,
  // if this is a sub-process, executes the appropriate logic.
  int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info);
  if (exit_code >= 0) {
    // The sub-process has completed so return here.
    return exit_code;
  }

  // Specify CEF global settings here.
  CefSettings settings;

#if !defined(CEF_USE_SANDBOX)
  settings.no_sandbox = true;
#endif

  // Initialize CEF.
  CefInitialize(main_args, settings, app.get(), sandbox_info);

  CMainFrame* pFrame = new CMainFrame();
  if (pFrame == NULL) return 0;
  HANDLE mainHandle = NULL;
#if defined(WIN32) && !defined(UNDER_CE)
  mainHandle = pFrame->Create(NULL, _T("PLApp"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 600, 800);
#else
  mainHandle = pFrame->Create(NULL, _T("PLApp"), UI_WNDSTYLE_DIALOG, WS_EX_TOPMOST, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
#endif

  pFrame->CenterWindow();
  ::ShowWindow(*pFrame, SW_SHOW);

  // Run the CEF message loop. This will block until CefQuitMessageLoop() is
  // called.
  CefRunMessageLoop();

  // Shut down CEF.
  CefShutdown();

  return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容