分享个Duilib中基于wke的浏览器控件

来源:互联网 发布:lua 5.1 windows 编辑:程序博客网 时间:2024/06/05 16:14

概述

wke是基于谷歌chrome浏览器源代码的裁剪版本,大小仅仅只有10M左右,无需依赖其他的扩展库(跟CEF的一大堆大约40M的DLL来比简直爽呆了),就可以在本地使用谷歌内核快速加载网页。网上也有基于wke在Duilib 上扩展的控件代码,其实wke头文件挺清楚的了,接口一目了然,特别是JS与C++交互的函数更是容易看懂,也没什么难的,你也可以做到的。

代码

毕竟是裁剪库,有的功能还是没有接口来处理的(比如网页加载前、页面跳转、菜单消息……),头文件代码:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #ifndef __UIWKEWEBKIT_H_  
  2. #define __UIWKEWEBKIT_H_  
  3. #pragma once  
  4. #include "wke.h"  
  5. #include <string>  
  6. using std::wstring;  
  7.   
  8. namespace DuiLib  
  9. {  
  10.     ///////////////////////////////////////////  
  11.     //网页加载状态改变的回调  
  12.     class CWkeWebkitLoadCallback  
  13.     {  
  14.     public:  
  15.         virtual void    OnLoadFailed()=0;  
  16.         virtual void    OnLoadComplete()=0;  
  17.         virtual void    OnDocumentReady()=0;  
  18.     };  
  19.     ///////////////////////////////////////////  
  20.     //网页标题、地址改变的回调  
  21.     class CWkeWebkitClientCallback  
  22.     {  
  23.     public:  
  24.         virtual void    OnTitleChange(const CDuiString& strTitle)=0;  
  25.         virtual void    OnUrlChange(const CDuiString& strUrl)=0;  
  26.     };  
  27.   
  28.     class CWkeWebkitUI :  
  29.         public CControlUI,  
  30.         public wkeBufHandler  
  31.     {  
  32.     public:  
  33.         CWkeWebkitUI(void);  
  34.         ~CWkeWebkitUI(void);  
  35.         virtual void    onBufUpdated (const HDC hdc,int x, int y, int cx, int cy);  
  36.         virtual LPCTSTR GetClass()const;  
  37.         virtual LPVOID  GetInterface(LPCTSTR pstrName);  
  38.         virtual void    DoEvent(TEventUI& event);  
  39.         virtual void    DoPaint(HDC hDC, const RECT& rcPaint);  
  40.         virtual void    SetPos(RECT rc);  
  41.         virtual void    DoInit();  
  42.         virtual void    SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);  
  43.         //////////////////////////////////////  
  44.         const   wstring& GetUrl()const ;  
  45.         bool    CanGoBack() const;  
  46.         bool    GoBack();  
  47.         bool    CanGoForward() const;  
  48.         bool    GoForward();  
  49.         void    StopLoad();  
  50.         void    Refresh();  
  51.         wkeWebView  GetWebView();  
  52.         void    SetLoadCallback(CWkeWebkitLoadCallback* pCallback);  
  53.         CWkeWebkitLoadCallback* GetLoadCallback();  
  54.         void    Navigate(LPCTSTR lpUrl);  
  55.         void    LoadFile(LPCTSTR lpFile);  
  56.         void    LoadHtml(LPCTSTR lpHtml);  
  57.     protected:  
  58.         void    StartCheckThread();  
  59.         void    StopCheckThread();  
  60.         static  void OnTitleChange(const struct _wkeClientHandler* clientHandler, const wkeString title);  
  61.         static  void OnUrlChange(const struct _wkeClientHandler* clientHandler, const wkeString url);  
  62.     private:  
  63.         static int  m_bWebkitCount;  
  64.         HANDLE      m_hCheckThread;  
  65.         wstring     m_strUrl;  
  66.         wkeWebView  m_pWebView;  
  67.         wkeClientHandler    m_ClientHandler;  
  68.         CWkeWebkitLoadCallback*     m_pLoadCallback;  
  69.         CWkeWebkitClientCallback*   m_pClientCallback;  
  70.     };  
  71. }  
  72.   
  73. #endif//__UIWKEWEBKIT_H_  

实现部分代码:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include "StdAfx.h"  
  2. #include "UIWkeWebkit.h"  
  3. #pragma comment(lib, "DuiEx/wke/wke")  
  4.   
  5. namespace DuiLib{  
  6. ///////////////////////////////////////////////////  
  7. //网页加载状态监测线程  
  8. DWORD WINAPI CheckThreadFun(LPVOID lpParam)  
  9. {  
  10.     CWkeWebkitUI* pWebkitUI=(CWkeWebkitUI*)lpParam;  
  11.     wkeWebView  pWebView=pWebkitUI->GetWebView();  
  12.     if ( NULL == pWebView )  
  13.         return 1;  
  14.     CWkeWebkitLoadCallback* pCallback=pWebkitUI->GetLoadCallback();  
  15.     if ( NULL == pCallback )  
  16.         return 1;  
  17.     bool bOver=false;  
  18.     while( !pWebView->isLoaded() )  
  19.     {  
  20.         if ( !bOver && pWebView->isDocumentReady() )  
  21.         {  
  22.             pCallback->OnDocumentReady();  
  23.             bOver=true;  
  24.         }  
  25.         if ( pWebView->isLoadFailed() )  
  26.         {  
  27.             pCallback->OnLoadFailed();  
  28.             return 1;  
  29.         }  
  30.         ::Sleep(30);  
  31.     }  
  32.     if ( pWebView->isLoadComplete() )  
  33.         pCallback->OnLoadComplete();  
  34.     return 0;  
  35. }  
  36.   
  37. //////////////////////////////////////////////////////  
  38. int CWkeWebkitUI::m_bWebkitCount=0;  
  39. CWkeWebkitUI::CWkeWebkitUI(void)  
  40. :m_pWebView(NULL)  
  41. ,m_hCheckThread(NULL)  
  42. ,m_pLoadCallback(NULL)  
  43. ,m_pClientCallback(NULL)  
  44. {  
  45.     if ( 0 == m_bWebkitCount )  
  46.         wkeInit();  
  47.     m_pWebView=wkeCreateWebView();  
  48.     m_pWebView->setBufHandler(this);  
  49.     m_ClientHandler.onTitleChanged  =&CWkeWebkitUI::OnTitleChange;  
  50.     m_ClientHandler.onURLChanged    =&CWkeWebkitUI::OnUrlChange;  
  51.     m_bWebkitCount++;  
  52. }  
  53.   
  54. CWkeWebkitUI::~CWkeWebkitUI(void)  
  55. {  
  56.     StopCheckThread();  
  57.     m_pManager->KillTimer(this);  
  58.     wkeDestroyWebView(m_pWebView);  
  59.     m_bWebkitCount--;  
  60.     if ( 0 == m_bWebkitCount )  
  61.         wkeShutdown();  
  62. }  
  63.   
  64. LPCTSTR CWkeWebkitUI::GetClass() const  
  65. {  
  66.     return L"WkeWebkitUI";  
  67. }  
  68.   
  69. LPVOID CWkeWebkitUI::GetInterface( LPCTSTR pstrName )  
  70. {  
  71.     if( _tcscmp(pstrName, _T("WkeWebkit")) == 0 )   
  72.         return static_cast<CWkeWebkitUI*>(this);  
  73.     return CControlUI::GetInterface(pstrName);  
  74. }  
  75.   
  76. void CWkeWebkitUI::DoEvent( TEventUI& event )  
  77. {  
  78.     switch( event.Type )  
  79.     {  
  80.     case UIEVENT_SETFOCUS:  
  81.         if ( m_pWebView ) m_pWebView->focus(); break;  
  82.     case UIEVENT_KILLFOCUS:  
  83.         if ( m_pWebView ) m_pWebView->unfocus(); break;  
  84.     case UIEVENT_WINDOWSIZE:  
  85.         if ( m_pWebView ) m_pWebView->resize(GET_X_LPARAM(event.lParam), GET_Y_LPARAM(event.lParam)); break;  
  86.     case UIEVENT_CHAR:  
  87.         {  
  88.             if ( NULL == m_pWebView ) break;  
  89.             unsigned int charCode = event.wParam;  
  90.             unsigned int flags = 0;  
  91.             if (HIWORD(event.lParam) & KF_REPEAT)  
  92.                 flags |= WKE_REPEAT;  
  93.             if (HIWORD(event.lParam) & KF_EXTENDED)  
  94.                 flags |= WKE_EXTENDED;  
  95.             bool bHandled=m_pWebView->keyPress(charCode, flags, false);  
  96.             if ( bHandled )  
  97.                 return ;  
  98.             break;  
  99.         }  
  100.     case UIEVENT_KEYDOWN:  
  101.         {  
  102.             if ( NULL == m_pWebView ) break;  
  103.             unsigned int flags = 0;  
  104.             if (HIWORD(event.lParam) & KF_REPEAT)  
  105.                 flags |= WKE_REPEAT;  
  106.             if (HIWORD(event.lParam) & KF_EXTENDED)  
  107.                 flags |= WKE_EXTENDED;  
  108.             bool bHandled=m_pWebView->keyDown(event.wParam, flags, false);  
  109.             if ( event.wParam == VK_F5 )  
  110.                 Refresh();  
  111.             if ( bHandled )  
  112.                 return ;  
  113.             break;  
  114.         }  
  115.     case UIEVENT_KEYUP:  
  116.         {  
  117.             if ( NULL == m_pWebView ) break;  
  118.             unsigned int flags = 0;  
  119.             if (HIWORD(event.lParam) & KF_REPEAT)  
  120.                 flags |= WKE_REPEAT;  
  121.             if (HIWORD(event.lParam) & KF_EXTENDED)  
  122.                 flags |= WKE_EXTENDED;  
  123.             bool bHandled=m_pWebView->keyUp(event.wParam, flags, false);  
  124.             if ( bHandled )  
  125.                 return ;  
  126.             break;  
  127.         }  
  128.     case UIEVENT_CONTEXTMENU:  
  129.         {  
  130.             if ( NULL == m_pWebView ) break;  
  131.             unsigned int flags = 0;  
  132.             if (event.wParam & MK_CONTROL)  
  133.                 flags |= WKE_CONTROL;  
  134.             if (event.wParam & MK_SHIFT)  
  135.                 flags |= WKE_SHIFT;  
  136.             if (event.wParam & MK_LBUTTON)  
  137.                 flags |= WKE_LBUTTON;  
  138.             if (event.wParam & MK_MBUTTON)  
  139.                 flags |= WKE_MBUTTON;  
  140.             if (event.wParam & MK_RBUTTON)  
  141.                 flags |= WKE_RBUTTON;  
  142.             bool handled = m_pWebView->contextMenuEvent(event.ptMouse.x, event.ptMouse.y, flags);  
  143.             if ( handled )  
  144.                 return ;  
  145.             break;  
  146.         }  
  147.     case UIEVENT_MOUSEMOVE:  
  148.     case UIEVENT_BUTTONDOWN:  
  149.     case UIEVENT_BUTTONUP:  
  150.     case UIEVENT_RBUTTONDOWN:  
  151.     case UIEVENT_DBLCLICK:  
  152.         {  
  153.             HWND hWnd=m_pManager->GetPaintWindow();  
  154.             if ( event.Type == UIEVENT_BUTTONDOWN )  
  155.             {  
  156.                 ::SetFocus(hWnd);  
  157.                 SetCapture(hWnd);  
  158.             }  
  159.             else if ( event.Type == UIEVENT_BUTTONUP )  
  160.                 ReleaseCapture();  
  161.             unsigned int flags = 0;  
  162.             if (event.wParam & MK_CONTROL)  
  163.                 flags |= WKE_CONTROL;  
  164.             if (event.wParam & MK_SHIFT)  
  165.                 flags |= WKE_SHIFT;  
  166.   
  167.             if (event.wParam & MK_LBUTTON)  
  168.                 flags |= WKE_LBUTTON;  
  169.             if (event.wParam & MK_MBUTTON)  
  170.                 flags |= WKE_MBUTTON;  
  171.             if (event.wParam & MK_RBUTTON)  
  172.                 flags |= WKE_RBUTTON;  
  173.             UINT uMsg=0;  
  174.             switch ( event.Type )  
  175.             {  
  176.             case UIEVENT_BUTTONDOWN:    uMsg=WM_LBUTTONDOWN; break;  
  177.             case UIEVENT_BUTTONUP:      uMsg=WM_LBUTTONUP; break;  
  178.             case UIEVENT_RBUTTONDOWN:   uMsg=WM_RBUTTONDOWN; break;  
  179.             case UIEVENT_DBLCLICK:      uMsg=WM_LBUTTONDBLCLK; break;  
  180.             case UIEVENT_MOUSEMOVE:     uMsg=WM_MOUSEMOVE; break;  
  181.             }  
  182.             bool bHandled = m_pWebView->mouseEvent(uMsg, event.ptMouse.x-m_rcItem.left, \  
  183.                 event.ptMouse.y-m_rcItem.top, flags);  
  184.             if ( bHandled )  
  185.                 return ;  
  186.             break;  
  187.         }  
  188.     case UIEVENT_TIMER:  
  189.         if ( m_pWebView )  
  190.             m_pWebView->tick();  
  191.         break;  
  192.     case UIEVENT_SCROLLWHEEL:  
  193.         {  
  194.             POINT pt;  
  195.             pt.x = LOWORD(event.lParam);  
  196.             pt.y = HIWORD(event.lParam);  
  197.             int nFlag=GET_X_LPARAM(event.wParam);  
  198.             int delta = (nFlag==SB_LINEDOWN)?-120:120;  
  199.             unsigned int flags = 0;  
  200.             if (event.wParam & MK_CONTROL)  
  201.                 flags |= WKE_CONTROL;  
  202.             if (event.wParam & MK_SHIFT)  
  203.                 flags |= WKE_SHIFT;  
  204.             if (event.wParam & MK_LBUTTON)  
  205.                 flags |= WKE_LBUTTON;  
  206.             if (event.wParam & MK_MBUTTON)  
  207.                 flags |= WKE_MBUTTON;  
  208.             if (event.wParam & MK_RBUTTON)  
  209.                 flags |= WKE_RBUTTON;  
  210.             bool handled = m_pWebView->mouseWheel(pt.x, pt.y, delta, flags);  
  211.             if ( handled )  
  212.                 return ;  
  213.             break;  
  214.         }  
  215.     default:  
  216.         CControlUI::DoEvent(event); break;  
  217.     }  
  218. }  
  219.   
  220. void CWkeWebkitUI::DoPaint( HDC hDC, const RECT& rcPaint )  
  221. {  
  222.     if ( m_pWebView )  
  223.     {  
  224.         RECT rcInsert;  
  225.         IntersectRect(&rcInsert, &m_rcItem, &rcPaint);  
  226.         m_pWebView->paint(hDC, rcInsert.left, rcInsert.top, \  
  227.             rcInsert.right-rcInsert.left, rcInsert.bottom-rcInsert.top, \  
  228.             rcInsert.left-m_rcItem.left, rcInsert.top-m_rcItem.top, true);  
  229.     }  
  230. }  
  231.   
  232. void CWkeWebkitUI::onBufUpdated( const HDC hdc,int x, int y, int cx, int cy )  
  233. {  
  234.     RECT rcValide={ x, y, x+cx, y+cy };  
  235.     ::OffsetRect(&rcValide, m_rcItem.left, m_rcItem.top);  
  236.     HWND hWnd=m_pManager->GetPaintWindow();  
  237.     ::InvalidateRect(hWnd, &rcValide, TRUE);  
  238. }  
  239.   
  240. void CWkeWebkitUI::Navigate( LPCTSTR lpUrl )  
  241. {  
  242.     if ( m_pWebView )  
  243.     {  
  244.         m_pWebView->loadURL(lpUrl);  
  245.         StartCheckThread();  
  246.     }  
  247. }  
  248.   
  249. void CWkeWebkitUI::SetPos( RECT rc )  
  250. {  
  251.     CControlUI::SetPos(rc);  
  252.     if ( m_pWebView )  
  253.         m_pWebView->resize(rc.right-rc.left, rc.bottom-rc.top);  
  254. }  
  255.   
  256. void CWkeWebkitUI::DoInit()  
  257. {  
  258.     if ( !m_strUrl.empty() )  
  259.         Navigate(m_strUrl.c_str());  
  260.     m_pManager->SetTimer(this, 100, 100);  
  261. }  
  262.   
  263. void CWkeWebkitUI::StartCheckThread()  
  264. {  
  265.     StopCheckThread();  
  266.     m_hCheckThread=::CreateThread(NULL, 0, CheckThreadFun, this, 0, NULL);  
  267. }  
  268.   
  269. void CWkeWebkitUI::StopCheckThread()  
  270. {  
  271.     if ( m_hCheckThread )  
  272.     {  
  273.         if ( ::WaitForSingleObject(m_hCheckThread, 10) != WAIT_OBJECT_0 )  
  274.             ::TerminateThread(m_hCheckThread, 0);  
  275.         ::CloseHandle(m_hCheckThread);  
  276.         m_hCheckThread = NULL;  
  277.     }  
  278. }  
  279.   
  280. bool CWkeWebkitUI::CanGoBack() const  
  281. {  
  282.     return m_pWebView?m_pWebView->canGoBack():false;  
  283. }  
  284.   
  285. bool CWkeWebkitUI::GoBack()  
  286. {  
  287.     return m_pWebView?m_pWebView->goBack():false;  
  288. }  
  289.   
  290. bool CWkeWebkitUI::CanGoForward() const  
  291. {  
  292.     return m_pWebView?m_pWebView->canGoForward():false;  
  293. }  
  294.   
  295. bool CWkeWebkitUI::GoForward()  
  296. {  
  297.     return m_pWebView?m_pWebView->goForward():false;  
  298. }  
  299.   
  300. void CWkeWebkitUI::StopLoad()  
  301. {  
  302.     if ( m_pWebView )  
  303.         m_pWebView->stopLoading();  
  304. }  
  305.   
  306. void CWkeWebkitUI::Refresh()  
  307. {  
  308.     if ( m_pWebView )  
  309.     {  
  310.         StopCheckThread();  
  311.         m_pWebView->reload();  
  312.         StartCheckThread();  
  313.     }  
  314. }  
  315.   
  316. wkeWebView CWkeWebkitUI::GetWebView()  
  317. {  
  318.     return m_pWebView;  
  319. }  
  320.   
  321. void CWkeWebkitUI::SetLoadCallback( CWkeWebkitLoadCallback* pCallback )  
  322. {  
  323.     m_pLoadCallback=pCallback;  
  324. }  
  325.   
  326. CWkeWebkitLoadCallback* CWkeWebkitUI::GetLoadCallback()  
  327. {  
  328.     return m_pLoadCallback;  
  329. }  
  330.   
  331. void CWkeWebkitUI::OnTitleChange( const struct _wkeClientHandler* clientHandler, const wkeString title )  
  332. {  
  333.   
  334. }  
  335.   
  336. void CWkeWebkitUI::OnUrlChange( const struct _wkeClientHandler* clientHandler, const wkeString url )  
  337. {  
  338.   
  339. }  
  340.   
  341. void CWkeWebkitUI::LoadFile( LPCTSTR lpFile )  
  342. {  
  343.     if ( m_pWebView )  
  344.         m_pWebView->loadFile(lpFile);  
  345. }  
  346.   
  347. void CWkeWebkitUI::LoadHtml( LPCTSTR lpHtml )  
  348. {  
  349.     if ( m_pWebView )  
  350.         m_pWebView->loadHTML(lpHtml);  
  351. }  
  352.   
  353. const wstring& CWkeWebkitUI::GetUrl() const  
  354. {  
  355.     return m_strUrl;  
  356. }  
  357.   
  358. void CWkeWebkitUI::SetAttribute( LPCTSTR pstrName, LPCTSTR pstrValue )  
  359. {  
  360.     if ( _tcscmp(pstrName, _T("url")) == 0 )  
  361.         m_strUrl = pstrValue;  
  362.     else  
  363.         CControlUI::SetAttribute(pstrName, pstrValue);  
  364. }  
  365.   
  366. }  

解析:

主要处理的就是消息部分,把这个区域的那种消息分发给wke的接口去处理。另外就是加了个线程,检测网页加载状态,通过回调通知网页加载完成、失败、DOC完成(需要用户先初始化回调指针才会通知用户)。

控件定义完成后,我们需要来配置XML了:

<WkeWebkit name="webkit1" url="http://192.168.1.20:92/?mainctl=chrome&version=1.2.3"/>

放在一个布局里面,指定URL即可,你也可以加上其他属性然后在SetAttribute中对这些属性进行初始化。

运行程序,一个无窗口的chrome内核网页控件就展示出来了:


后记

wke加载网页只能用于展示以及JS交互处理,毕竟裁剪后还是要失去很多其他功能的,对于chrome内核10M的大小已经是相当的不错了,另外还有一个EaWebkit也是基于chrome的扩展,编译成DLL后只有6M左右,也是开源的,大家可以网上看看。


1 0
原创粉丝点击