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

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM