概述

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

代码

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

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

实现部分代码:

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

解析:

主要处理的就是消息部分,把这个区域的那种消息分发给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左右,也是开源的,大家可以网上看看。

分享个Duilib中基于wke的浏览器控件相关推荐

  1. 基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成

    基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成 背景 实现目标 实现代码 运行效果 完整的代码及依赖jar文件下载 背景 进期客户提出在一个Java Swing项目要集成另 ...

  2. 如何在PB中调用 Microsoft WEB 浏览器 控件?

    PB中使用Microsoft Web Browser控件步骤: 在pb的某窗口中加入OLE对象,选择Insert control(插入控件),然后选中"Microsoft WEB 浏览器&q ...

  3. python webkit内核_Winform调用WebKitBrowser,基于chrome内核WebKit的浏览器控件

    在C#中,默认的WebBrowser控件默认使用的是IE的core,而IE的种种遭人吐槽的诟病使我不敢轻易使用WebBrowser,因此,打算使用Chrome的内核替换IE.Chrome的内核使用的是 ...

  4. C# .NET 6.0已经取消了Framework 4.8的WebBrowser控件,几款NuGet中的浏览器控件介绍

    即使在C# .NET 6.0..NET 7.0在选择工具箱项COM组件添加Microsoft Web Browser,工具箱也没有WebBrowser控件. WebBrowser控件: WebBrow ...

  5. java程序获取外部java程序的控件,将 Java 小程序迁移到 Microsoft J# 浏览器控件-JSP教程,Java技巧及代码...

    visual j# .net 小组 microsoft corporation 摘要:通过 microsoft j# 浏览器控件,开发人员可以将所编写的在 java 虚拟机上运行的 java 小程序迁 ...

  6. Winform中将WebBrower浏览器控件由IE内核修改为Chrome的WebKit内核

    场景 Winform中自带一个浏览器控件WebBrower控件,使用此控件可以很轻易的实现一个桌面端的 浏览器. 新建Winform程序,然后在设计页面在工具箱中拖拽一个WebBrower控件. 然后 ...

  7. 收藏夹导出至html,分享win7电脑中三种导出浏览器收藏夹地址方法

    使用win7电脑浏览器访问网站时为了更方便之后的访问用户都会讲有需要的网站收藏,但是有些用户在使用浏览器时并不习惯登陆账户就会导致收藏夹无法同步,之后电脑出现故障时或是浏览器出现问题收藏内容就会消失, ...

  8. 在Delphi程序中应用IE浏览器控件

    ---- 大概大家还记得Delphi的范例程序中的那个浏览器的例子吧.在那个例子中,利用控件THttp的属性和方法制作了一个浏览器.该例子用于理解THttp控件的使用方法,确实不错.但很少有人会用它作 ...

  9. net中winform教程 浏览器控件,还是微软的WebView2最好用

    如果想在Winform项目中使用浏览器控件,可能想到的第一个控件就是微软自带的WebBrowser,可这个不争气的家伙,从出现到现在,没有一丁点的升级,即使身为Net程序员,也不得不对它竖起了中指.不 ...

  10. Silverlight4.0教程之WebBrowser控件(Silverlight内置HTML浏览器控件)

    微软于PDC2009上发布Silverlight 4 Beta版,微软在Silverlight 4版本中处理了约8000个的Silverlight终端用户的请求,加入了一系列另开发人员兴奋的新特性,最 ...

最新文章

  1. lab_2 Selenium
  2. MS的.net源码地址
  3. Qt Creator如何恢复默认布局
  4. Mac 的World空格显示为.
  5. openflow多级流表机制的优点?
  6. HDU多校1 - 6955 Xor sum(字典树+贪心)
  7. 感性电路电流计算_220和380V功率和电流计算知识。
  8. SpringCloud day12
  9. 通用横轴墨卡托投影(Universal Transvers Mercator)
  10. vue h5项目集成环信webIM超详细步骤,附代码注释讲解
  11. gif动态图太大如何发微信?手机如何快速压缩动图?
  12. ECCV 2020 论文大盘点-目标跟踪篇
  13. 【2022国赛模拟】摆(bigben)——行列式、杜教筛
  14. ES5 to ESNext —  自 2015 以来 JavaScript 新增的所有新特性
  15. redhat 7中DNS 服务器配置与测试
  16. linux Xinetd服务简介
  17. 办公最常用哪个邮箱?怎么申请商务邮箱?
  18. 东北天、地心地固、WGS84转换-代码
  19. CPLEX+Yalmip的MATLAB环境安装
  20. 爬虫入门——爬虫可以采集哪些格式的数据?

热门文章

  1. 计算机应用基础题excel,计算机应用基础专练习题excel.doc
  2. 2022 电工杯 B 物资配送 全部图解
  3. 106个计算机学部毕业设计项目大全(附源码)
  4. 传奇DBC数据库变量详细解释传奇DB文件详解
  5. 开机未发现nvidia控制面板_Nvidia控制面板打不开,怎么办?
  6. 【韩顺平 零基础30天学会Java】(第三阶段)(自用)
  7. NoSQL数据库原理与应用
  8. vue+element 表格el-table显示数据加载中
  9. 怎么批量查找关键词-批量查找关键词软件工具
  10. newifi3 高恪魔改_新路由3高恪newifi3固件-支持512M