• cef3和duilib简单仿有道词典学习


      由于最近换工作的原因,也没啥事,就简单学习了一下cef3duilib,楼主之前是做MFC框架下的windows开发的,对界面库和新的客户端开发模式也有所了解,现在的大部分客户端都是基本的客户端框架下组合一个web 容器,web容器当然要看google的开源引擎cef3了,像Qt最近的版本好像也集成了,钉钉,微信、这些桌面应用都是基于web的客户端来开发的。

      所以楼主就也想学习一下,学习东西最快的方式就是做项目!!!所以我选择了duilib做界面,因为这个库是基于win32的,也是开源的,我也比较熟悉,然后web引擎当然是cef3了,开源的。花了一个星期吧话不多说,先放图

      主界面:

        

      动态图演示:

    程序实现简单介绍:

      软件包括部分:界面绘图+容器填充。

      一开始我是先在Github上面下载了开源的duilib,然后看了看,模仿了里面的几个Demo例子,就开始动手。

    Duilib界面设计,一部分是手写xml,这个我相信大家看了几个Demo之后就可以上手写了,然后再看一下网上的几篇布局的教程,Redrain写的,就可以了,界面控件与XML文件控件的对应关系要理解,实现的时候我是使用了 WindowImplBase这个类,所有与界面相关的操作只需要继承这个即可完成,实现简单的功能无非就是按钮的响应,按钮的选择等等,这些只需要到Notify(TNotifyUI& msg);函数中去处理,细节不多说,Duilib是可以根据xml中的控件名字去映射到控件类,

    1 CTabLayoutUI*pTabTest=static_cast<CTabLayoutUI*>(m_PaintManager.FindControl(_T("tabTest")));

      以上语句就是通过xml中的tabTest去定位到pTabTest,所有的控件都可以这样定位,定位到控件就简单了,剩下的控件操作看duilib提供的API文档即可。

      下面是界面的主界面类,包含web容器窗口的调整,主界面控件响应的操作实现,相信看过两次duilib的人都能看懂,这下面的WindowImplBase的虚函数接口是自己要实现的,

     1 class CMainFrame : public WindowImplBase
     2 {
     3 public:
     4     CMainFrame();
     5     virtual ~CMainFrame();
     6 public:
     7     LPCTSTR GetWindowClassName() const;    
     8     virtual void OnFinalMessage(HWND hWnd);
     9     virtual void InitWindow();
    10     virtual LRESULT ResponseDefaultKeyEvent(WPARAM wParam);
    11     virtual UILIB_RESOURCETYPE GetResourceType() const;
    12     virtual CDuiString GetSkinFile();
    13     virtual CDuiString GetSkinFolder();
    14     virtual CControlUI* CreateControl(LPCTSTR pstrClass);
    15     virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
    16     virtual LRESULT OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    17     virtual LRESULT HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    18     virtual LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
    19     void FirstLoadCef();
    20     void HideCefWindow();
    21     HWND GetMainWnd(){ return this->m_hWnd; }
    22 protected:    
    23     void Notify(TNotifyUI& msg);
    24     void OnPrepare(TNotifyUI& msg);
    25     void OnExit(TNotifyUI& msg);
    26     void OnTimer(TNotifyUI& msg);
    27     //
    28     void OnSelChanged(CControlUI* pSender);
    29     void OnClick(CControlUI * pSender);
    30     //cef
    31     void AdjustCefWindow();
    32     void UpdateTransString(int nNum);
    33     //create wnd
    34     void ShowTransSelectFrame();
    35     void ShowWordClassifyFrame();
    36     void ShowWordSortFrame();
    37     void ShowWordManagerFrame();
    38     void HideLayoutFrame();
    39     void ShowMiniModeFrame();
    40 private:
    41     BOOL     m_bIsInit;
    42     CTransSelectWnd *m_pTransSelectFrame;
    43     CWordClassifyWnd *m_pWordClassifyFrame;
    44     CWordSortWnd *m_pWordSortFrame;
    45     CWordManagerWnd *m_pWordManagerFrame;
    46     CMiniModeWnd *m_pMiniModeFrame;
    47 };

      界面实现就不写了,源码会分享给大家的。

      容器填充,就是通过cef3内核加载web界面了,这个也不难,复杂的功能我没用到,只是简单启动了一个cef3的浏览器渲染进程,

      这里只实现了两个类,就满足了要求:cef进程实例类和和维护具体浏览器句柄类,

     1 class SimpleApp 
     2     : public CefApp
     3     , public CefBrowserProcessHandler 
     4 {
     5 public:
     6     SimpleApp();
     7     virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
     8         OVERRIDE{ return this; }
     9     virtual void OnContextInitialized() OVERRIDE;
    10 private:
    11     IMPLEMENT_REFCOUNTING(SimpleApp);
    12 };
    13 
    14 class SimpleHandler 
    15     : public CefClient
    16     , public CefDisplayHandler
    17     , public CefLifeSpanHandler
    18 {
    19 public:
    20     SimpleHandler();
    21     virtual ~SimpleHandler();
    22     virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE
    23     {
    24         return this;
    25     }
    26     virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
    27     {
    28         return this;
    29     }
    30 
    31     virtual void OnTitleChange(CefRefPtr<CefBrowser> browser,const CefString& title) OVERRIDE;
    32     virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
    33     virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
    34     CefRefPtr<CefBrowser> GetCurrentBrowser();
    35 private:
    36     typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
    37     BrowserList browser_list_;
    38 
    39 private:
    40     IMPLEMENT_REFCOUNTING(SimpleHandler);
    41 };

      两个类足够了,主函数启动的代码,

     1 CPaintManagerUI::SetInstance(hInstance);
     2 #if defined(WIN32) && !defined(UNDER_CE)
     3     HRESULT Hr = ::CoInitialize(NULL);
     4 #else
     5     HRESULT Hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
     6 #endif
     7     if( FAILED(Hr) ) return 0;
     8     CefMainArgs args(hInstance);
     9     //创建CefApp实例
    10     CefRefPtr<SimpleApp> app(new SimpleApp);
    11     int exitCode = CefExecuteProcess(args, app, NULL);
    12     if (exitCode >= 0)
    13     {
    14         return exitCode;
    15     }
    16     //填充这个结构体,定制CEF的行为。
    17     CefSettings settings;
    18     //初始化CEF
    19     CefInitialize(args, settings, app, NULL);
    20     CMainFrame* pFrame = new CMainFrame();
    21     if( pFrame == NULL ) return 0;
    22 #if defined(WIN32) && !defined(UNDER_CE)
    23     pFrame->Create(NULL, _T("PLApp"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 600, 800);
    24 #else
    25     pFrame->Create(NULL, _T("PLApp"), UI_WNDSTYLE_DIALOG, WS_EX_TOPMOST, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
    26 #endif
    27     HICON hIcon = ::LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    28     ::SendMessage(*pFrame, STM_SETICON, IMAGE_ICON, (LPARAM)(UINT)hIcon);
    29 
    30     pFrame->CenterWindow();
    31     ::ShowWindow(*pFrame, SW_SHOW);
    32     //执行消息循环,此时会堵塞,直到CefQuitMessageLoop()函数被调用。
    33     CefRunMessageLoop();
    34     // 关闭CEF,释放资源  
    35     CefShutdown();

      加载浏览器的关键实现,使用g_handler句柄来操作,

    1 CefRefPtr<SimpleHandler> g_handler(new SimpleHandler());
    2 CefBrowserSettings browser_settings;
    3 CefWindowInfo window_info;
    4 window_info.SetAsChild(m_hWnd, rt);
    5 BOOL bSucced = CefBrowserHost::CreateBrowser(window_info
    6         , g_handler
    7         , _T("http://dict.youdao.com/?keyfrom=cidian")
    8         , browser_settings
    9         , NULL);

     

      关于以上代码的具体的功能解释我也不多说了,最近工作太累,博客也是刚更新的,希望这个我自己学习的代码对大家有点帮助,开放给大家,对cef3duilib学习起到参考入门的作用,代码放在这里了,github : https://github.com/karllen/cef3-duilib-YDDemo  。

    好了,博客完事,睡觉,明天看勇士和骑士的第四场比赛。

      对了:有道词典的一切资源文件归有道所有,禁止大家使用于商业用途,这个项目,仅供新手学习参考,如有侵权,联系我删除吧。

     

                                                                                   邮箱 :1160113606@qq.com

     

     

     

     

  • 相关阅读:
    Backbone.js 1.0.0源码架构分析(一)
    汤姆大叔的博客(深入理解JavaScript系列(2):揭秘命名函数表达式)
    求职之路(拿到百度、美团、趋势科技、华为offer)
    请大家注意这个网站www.haogongju.net
    后缀数组求最长重复子串
    2015阿里在线笔试题求两个字符串的最长子串
    剑指offer42:翻转单词顺序 VS 左旋转字符串(更高效、简便的解法)
    求和为s的连续正数序列
    数组中的逆序对
    求一串字符串的全排列和所有组合
  • 原文地址:https://www.cnblogs.com/Forever-Kenlen-Ja/p/6974345.html
Copyright © 2020-2023  润新知