duilib+CEF学习

DuilibAndCef

学习Duilib和Cef联合开发

编译duilib和Cef

下载duilib我这里选择网易云修改版,看起来界面好像比原版好看点
而且cef库也给封装好了

 git clone https://github.com/netease-im/NIM_Duilib_Framework

新建工程

新建一个 Windows 桌面程序后,将生成的代码清理一下只保留 wWinMain 函数。

然后把我们之前下载的几个项目给拷贝到我们项目的根目录

然后配置项目属性所有平台的属性设置输出目录和中间文件就好

将 Debug 模式的运行库修改为 /MTd,将 Release 模式的运行库修改为 /MT

项目右键->添加->引用,将 base、shared、duilib 作为引用项目,这样就不需要手动引入静态库文件了。

在 stdafx.h 中引入所需的头文件,这里目前只用到最基础的,所有添加这两个即可

// base header
#include "base/base.h"

// duilib
#include "duilib/UIlib.h"

但是用到一些ui或者cef控件的话还要添加

// base header
#include "base/base.h"

// duilib
#include "duilib/UIlib.h"

// ui components
#include "ui_components/ui_components.h"
#include "ui_components/ui_cef_control.h"

到这里框架基本结束了

编写代码

在创建的项目中 wWinMain 所属的头文件中,增加自定义的主线程对象。

/** @class MainThread
* @brief 主线程(UI线程)类,继承 nbase::FrameworkThread
* @copyright (c) 2015, NetEase Inc. All rights reserved
* @author towik
* @date 2015/1/1
*/
class MainThread : public nbase::FrameworkThread
{
public:
    MainThread() : nbase::FrameworkThread("MainThread") {}
    virtual ~MainThread() {}

private:
    /**
    * 虚函数,初始化主线程
    * @return void    无返回值
    */
    virtual void Init() override;

    /**
    * 虚函数,主线程退出时,做一些清理工作
    * @return void    无返回值
    */
    virtual void Cleanup() override;
};

在WinMain函数同文件内先实现上面两个函数

void MainThread::Init()
{
    nbase::ThreadManager::RegisterThread(kThreadUI);

    // 获取资源路径,初始化全局参数
    std::wstring theme_dir = nbase::win32::GetCurrentModuleDirectory();
    // Debug 模式下使用本地文件夹作为资源
    // 默认皮肤使用 resources\themes\default
    // 默认语言使用 resources\lang\zh_CN
    // 如需修改请指定 Startup 最后两个参数
    ui::GlobalManager::Startup(theme_dir + L"resources\", ui::CreateControlCallback(), false);
}
void MainThread::Cleanup()
{
    ui::GlobalManager::Shutdown();
    SetThreadWasQuitProperly(true);
    nbase::ThreadManager::UnregisterThread();
}

创建一个窗口类,继承 ui::WindowImplBase 类,并覆写 GetSkinFolder GetSkinFile GetWindowClassName 三个方法。

class MainWndFrame :
    public ui::WindowImplBase
{
public:
    MainWndFrame();
    ~MainWndFrame();

    /**
    * 一下三个接口是必须要覆写的接口,父类会调用这三个接口来构建窗口
    * GetSkinFolder        接口设置你要绘制的窗口皮肤资源路径
    * GetSkinFile            接口设置你要绘制的窗口的 xml 描述文件
    * GetWindowClassName    接口设置窗口唯一的类名称
    */
    virtual std::wstring GetSkinFolder() override;
    virtual std::wstring GetSkinFile() override;
    virtual std::wstring GetWindowClassName() const override;

    /**
    * 收到 WM_CREATE 消息时该函数会被调用,通常做一些控件初始化的操作
    */
    virtual void InitWindow() override;

    /**
    * 收到 WM_CLOSE 消息时该函数会被调用
    */
    virtual LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

    static const std::wstring kClassName;
};
const std::wstring MainWndFrame::kClassName = L"MyStudyDuilib";
MainWndFrame::MainWndFrame()
{
}


MainWndFrame::~MainWndFrame()
{
}

std::wstring MainWndFrame::GetSkinFolder()
{
    return L"basic";
}

std::wstring MainWndFrame::GetSkinFile()
{
    return L"basic.xml";
}

std::wstring MainWndFrame::GetWindowClassName() const
{
    return kClassName;
}

void MainWndFrame::InitWindow()
{
    // 做一些初始化工作
}

LRESULT MainWndFrame::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
    PostQuitMessage(0L);
    return __super::OnClose(uMsg, wParam, lParam, bHandled);
}

编写XML文件,因为上面设置xml名字和路径的原因,所以要在生成exe的目录下resources hemesdefaultasicasic.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Window size="800,600" caption="0,0,0,35">
  <VBox bkcolor="bk_wnd_darkcolor">
    <HBox width="stretch" height="35" bkcolor="bk_wnd_lightcolor">
      <Control />
      <Button class="btn_wnd_min" name="minbtn" margin="4,6,0,0"/>
      <Box width="21" margin="4,6,0,0">
        <Button class="btn_wnd_max" name="maxbtn"/>
        <Button class="btn_wnd_restore" name="restorebtn" visible="false"/>
      </Box>
      <Button class="btn_wnd_close" name="closebtn" margin="4,6,8,0"/>
    </HBox>
    <Box>
      <VBox margin="0,0,0,0" valign="center" halign="center" width="auto" height="auto">
        <Label name="tooltip" text="This is a baisc window form created by nim duilib."/>
      </VBox>
    </Box>
  </VBox>
</Window>

显示窗口
在主线程的 Init 方法中,创建窗口并居中显示,创建窗口前先引入窗口的头文件,修改后的代码如下:

void MainThread::Init()
{
    nbase::ThreadManager::RegisterThread(kThreadUI);

    // 获取资源路径,初始化全局参数
    std::wstring theme_dir = nbase::win32::GetCurrentModuleDirectory();
    // Debug 模式下使用本地文件夹作为资源
    // 默认皮肤使用 resources\themes\default
    // 默认语言使用 resources\lang\zh_CN
    // 如需修改请指定 Startup 最后两个参数
    ui::GlobalManager::Startup(theme_dir + L"resources\", ui::CreateControlCallback(), false);


    // 创建一个默认带有阴影的居中窗口
    MainWndFrame* window = new MainWndFrame();
    window->Create(NULL, MainWndFrame::kClassName.c_str(), WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX, 0);
    window->CenterWindow();
    window->ShowWindow();
}

参考链接

CEF参考文档
duilib教程

原文地址:https://www.cnblogs.com/fangaojun/p/13238069.html