-
分享个Duilib中基于wke的浏览器控件
概述
wke是基于谷歌chrome浏览器源代码的裁剪版本,大小仅仅只有10M左右,无需依赖其他的扩展库(跟CEF的一大堆大约40M的DLL来比简直爽呆了),就可以在本地使用谷歌内核快速加载网页。网上也有基于wke在Duilib 上扩展的控件代码,其实wke头文件挺清楚的了,接口一目了然,特别是JS与C++交互的函数更是容易看懂,也没什么难的,你也可以做到的。
代码
毕竟是裁剪库,有的功能还是没有接口来处理的(比如网页加载前、页面跳转、菜单消息……),头文件代码:
- #ifndef __UIWKEWEBKIT_H_
- #define __UIWKEWEBKIT_H_
- #pragma once
- #include "wke.h"
- #include <string>
- using std::wstring;
- namespace DuiLib
- {
- ///
- //网页加载状态改变的回调
- class CWkeWebkitLoadCallback
- {
- public:
- virtual void OnLoadFailed()=0;
- virtual void OnLoadComplete()=0;
- virtual void OnDocumentReady()=0;
- };
- ///
- //网页标题、地址改变的回调
- class CWkeWebkitClientCallback
- {
- public:
- virtual void OnTitleChange(const CDuiString& strTitle)=0;
- virtual void OnUrlChange(const CDuiString& strUrl)=0;
- };
- class CWkeWebkitUI :
- public CControlUI,
- public wkeBufHandler
- {
- public:
- CWkeWebkitUI(void);
- ~CWkeWebkitUI(void);
- virtual void onBufUpdated (const HDC hdc,int x, int y, int cx, int cy);
- virtual LPCTSTR GetClass()const;
- virtual LPVOID GetInterface(LPCTSTR pstrName);
- virtual void DoEvent(TEventUI& event);
- virtual void DoPaint(HDC hDC, const RECT& rcPaint);
- virtual void SetPos(RECT rc);
- virtual void DoInit();
- virtual void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
- //
- const wstring& GetUrl()const ;
- bool CanGoBack() const;
- bool GoBack();
- bool CanGoForward() const;
- bool GoForward();
- void StopLoad();
- void Refresh();
- wkeWebView GetWebView();
- void SetLoadCallback(CWkeWebkitLoadCallback* pCallback);
- CWkeWebkitLoadCallback* GetLoadCallback();
- void Navigate(LPCTSTR lpUrl);
- void LoadFile(LPCTSTR lpFile);
- void LoadHtml(LPCTSTR lpHtml);
- protected:
- void StartCheckThread();
- void StopCheckThread();
- static void OnTitleChange(const struct _wkeClientHandler* clientHandler, const wkeString title);
- static void OnUrlChange(const struct _wkeClientHandler* clientHandler, const wkeString url);
- private:
- static int m_bWebkitCount;
- HANDLE m_hCheckThread;
- wstring m_strUrl;
- wkeWebView m_pWebView;
- wkeClientHandler m_ClientHandler;
- CWkeWebkitLoadCallback* m_pLoadCallback;
- CWkeWebkitClientCallback* m_pClientCallback;
- };
- }
- #endif//__UIWKEWEBKIT_H_
实现部分代码:- #include "StdAfx.h"
- #include "UIWkeWebkit.h"
- #pragma comment(lib, "DuiEx/wke/wke")
- namespace DuiLib{
- ///
- //网页加载状态监测线程
- DWORD WINAPI CheckThreadFun(LPVOID lpParam)
- {
- CWkeWebkitUI* pWebkitUI=(CWkeWebkitUI*)lpParam;
- wkeWebView pWebView=pWebkitUI->GetWebView();
- if ( NULL == pWebView )
- return 1;
- CWkeWebkitLoadCallback* pCallback=pWebkitUI->GetLoadCallback();
- if ( NULL == pCallback )
- return 1;
- bool bOver=false;
- while( !pWebView->isLoaded() )
- {
- if ( !bOver && pWebView->isDocumentReady() )
- {
- pCallback->OnDocumentReady();
- bOver=true;
- }
- if ( pWebView->isLoadFailed() )
- {
- pCallback->OnLoadFailed();
- return 1;
- }
- ::Sleep(30);
- }
- if ( pWebView->isLoadComplete() )
- pCallback->OnLoadComplete();
- return 0;
- }
- //
- int CWkeWebkitUI::m_bWebkitCount=0;
- CWkeWebkitUI::CWkeWebkitUI(void)
- :m_pWebView(NULL)
- ,m_hCheckThread(NULL)
- ,m_pLoadCallback(NULL)
- ,m_pClientCallback(NULL)
- {
- if ( 0 == m_bWebkitCount )
- wkeInit();
- m_pWebView=wkeCreateWebView();
- m_pWebView->setBufHandler(this);
- m_ClientHandler.onTitleChanged =&CWkeWebkitUI::OnTitleChange;
- m_ClientHandler.onURLChanged =&CWkeWebkitUI::OnUrlChange;
- m_bWebkitCount++;
- }
- CWkeWebkitUI::~CWkeWebkitUI(void)
- {
- StopCheckThread();
- m_pManager->KillTimer(this);
- wkeDestroyWebView(m_pWebView);
- m_bWebkitCount--;
- if ( 0 == m_bWebkitCount )
- wkeShutdown();
- }
- LPCTSTR CWkeWebkitUI::GetClass() const
- {
- return L"WkeWebkitUI";
- }
- LPVOID CWkeWebkitUI::GetInterface( LPCTSTR pstrName )
- {
- if( _tcscmp(pstrName, _T("WkeWebkit")) == 0 )
- return static_cast<CWkeWebkitUI*>(this);
- return CControlUI::GetInterface(pstrName);
- }
- void CWkeWebkitUI::DoEvent( TEventUI& event )
- {
- switch( event.Type )
- {
- case UIEVENT_SETFOCUS:
- if ( m_pWebView ) m_pWebView->focus(); break;
- case UIEVENT_KILLFOCUS:
- if ( m_pWebView ) m_pWebView->unfocus(); break;
- case UIEVENT_WINDOWSIZE:
- if ( m_pWebView ) m_pWebView->resize(GET_X_LPARAM(event.lParam), GET_Y_LPARAM(event.lParam)); break;
- case UIEVENT_CHAR:
- {
- if ( NULL == m_pWebView ) break;
- unsigned int charCode = event.wParam;
- unsigned int flags = 0;
- if (HIWORD(event.lParam) & KF_REPEAT)
- flags |= WKE_REPEAT;
- if (HIWORD(event.lParam) & KF_EXTENDED)
- flags |= WKE_EXTENDED;
- bool bHandled=m_pWebView->keyPress(charCode, flags, false);
- if ( bHandled )
- return ;
- break;
- }
- case UIEVENT_KEYDOWN:
- {
- if ( NULL == m_pWebView ) break;
- unsigned int flags = 0;
- if (HIWORD(event.lParam) & KF_REPEAT)
- flags |= WKE_REPEAT;
- if (HIWORD(event.lParam) & KF_EXTENDED)
- flags |= WKE_EXTENDED;
- bool bHandled=m_pWebView->keyDown(event.wParam, flags, false);
- if ( event.wParam == VK_F5 )
- Refresh();
- if ( bHandled )
- return ;
- break;
- }
- case UIEVENT_KEYUP:
- {
- if ( NULL == m_pWebView ) break;
- unsigned int flags = 0;
- if (HIWORD(event.lParam) & KF_REPEAT)
- flags |= WKE_REPEAT;
- if (HIWORD(event.lParam) & KF_EXTENDED)
- flags |= WKE_EXTENDED;
- bool bHandled=m_pWebView->keyUp(event.wParam, flags, false);
- if ( bHandled )
- return ;
- break;
- }
- case UIEVENT_CONTEXTMENU:
- {
- if ( NULL == m_pWebView ) break;
- unsigned int flags = 0;
- if (event.wParam & MK_CONTROL)
- flags |= WKE_CONTROL;
- if (event.wParam & MK_SHIFT)
- flags |= WKE_SHIFT;
- if (event.wParam & MK_LBUTTON)
- flags |= WKE_LBUTTON;
- if (event.wParam & MK_MBUTTON)
- flags |= WKE_MBUTTON;
- if (event.wParam & MK_RBUTTON)
- flags |= WKE_RBUTTON;
- bool handled = m_pWebView->contextMenuEvent(event.ptMouse.x, event.ptMouse.y, flags);
- if ( handled )
- return ;
- break;
- }
- case UIEVENT_MOUSEMOVE:
- case UIEVENT_BUTTONDOWN:
- case UIEVENT_BUTTONUP:
- case UIEVENT_RBUTTONDOWN:
- case UIEVENT_DBLCLICK:
- {
- HWND hWnd=m_pManager->GetPaintWindow();
- if ( event.Type == UIEVENT_BUTTONDOWN )
- {
- ::SetFocus(hWnd);
- SetCapture(hWnd);
- }
- else if ( event.Type == UIEVENT_BUTTONUP )
- ReleaseCapture();
- unsigned int flags = 0;
- if (event.wParam & MK_CONTROL)
- flags |= WKE_CONTROL;
- if (event.wParam & MK_SHIFT)
- flags |= WKE_SHIFT;
- if (event.wParam & MK_LBUTTON)
- flags |= WKE_LBUTTON;
- if (event.wParam & MK_MBUTTON)
- flags |= WKE_MBUTTON;
- if (event.wParam & MK_RBUTTON)
- flags |= WKE_RBUTTON;
- UINT uMsg=0;
- switch ( event.Type )
- {
- case UIEVENT_BUTTONDOWN: uMsg=WM_LBUTTONDOWN; break;
- case UIEVENT_BUTTONUP: uMsg=WM_LBUTTONUP; break;
- case UIEVENT_RBUTTONDOWN: uMsg=WM_RBUTTONDOWN; break;
- case UIEVENT_DBLCLICK: uMsg=WM_LBUTTONDBLCLK; break;
- case UIEVENT_MOUSEMOVE: uMsg=WM_MOUSEMOVE; break;
- }
- bool bHandled = m_pWebView->mouseEvent(uMsg, event.ptMouse.x-m_rcItem.left, \
- event.ptMouse.y-m_rcItem.top, flags);
- if ( bHandled )
- return ;
- break;
- }
- case UIEVENT_TIMER:
- if ( m_pWebView )
- m_pWebView->tick();
- break;
- case UIEVENT_SCROLLWHEEL:
- {
- POINT pt;
- pt.x = LOWORD(event.lParam);
- pt.y = HIWORD(event.lParam);
- int nFlag=GET_X_LPARAM(event.wParam);
- int delta = (nFlag==SB_LINEDOWN)?-120:120;
- unsigned int flags = 0;
- if (event.wParam & MK_CONTROL)
- flags |= WKE_CONTROL;
- if (event.wParam & MK_SHIFT)
- flags |= WKE_SHIFT;
- if (event.wParam & MK_LBUTTON)
- flags |= WKE_LBUTTON;
- if (event.wParam & MK_MBUTTON)
- flags |= WKE_MBUTTON;
- if (event.wParam & MK_RBUTTON)
- flags |= WKE_RBUTTON;
- bool handled = m_pWebView->mouseWheel(pt.x, pt.y, delta, flags);
- if ( handled )
- return ;
- break;
- }
- default:
- CControlUI::DoEvent(event); break;
- }
- }
- void CWkeWebkitUI::DoPaint( HDC hDC, const RECT& rcPaint )
- {
- if ( m_pWebView )
- {
- RECT rcInsert;
- IntersectRect(&rcInsert, &m_rcItem, &rcPaint);
- m_pWebView->paint(hDC, rcInsert.left, rcInsert.top, \
- rcInsert.right-rcInsert.left, rcInsert.bottom-rcInsert.top, \
- rcInsert.left-m_rcItem.left, rcInsert.top-m_rcItem.top, true);
- }
- }
- void CWkeWebkitUI::onBufUpdated( const HDC hdc,int x, int y, int cx, int cy )
- {
- RECT rcValide={ x, y, x+cx, y+cy };
- ::OffsetRect(&rcValide, m_rcItem.left, m_rcItem.top);
- HWND hWnd=m_pManager->GetPaintWindow();
- ::InvalidateRect(hWnd, &rcValide, TRUE);
- }
- void CWkeWebkitUI::Navigate( LPCTSTR lpUrl )
- {
- if ( m_pWebView )
- {
- m_pWebView->loadURL(lpUrl);
- StartCheckThread();
- }
- }
- void CWkeWebkitUI::SetPos( RECT rc )
- {
- CControlUI::SetPos(rc);
- if ( m_pWebView )
- m_pWebView->resize(rc.right-rc.left, rc.bottom-rc.top);
- }
- void CWkeWebkitUI::DoInit()
- {
- if ( !m_strUrl.empty() )
- Navigate(m_strUrl.c_str());
- m_pManager->SetTimer(this, 100, 100);
- }
- void CWkeWebkitUI::StartCheckThread()
- {
- StopCheckThread();
- m_hCheckThread=::CreateThread(NULL, 0, CheckThreadFun, this, 0, NULL);
- }
- void CWkeWebkitUI::StopCheckThread()
- {
- if ( m_hCheckThread )
- {
- if ( ::WaitForSingleObject(m_hCheckThread, 10) != WAIT_OBJECT_0 )
- ::TerminateThread(m_hCheckThread, 0);
- ::CloseHandle(m_hCheckThread);
- m_hCheckThread = NULL;
- }
- }
- bool CWkeWebkitUI::CanGoBack() const
- {
- return m_pWebView?m_pWebView->canGoBack():false;
- }
- bool CWkeWebkitUI::GoBack()
- {
- return m_pWebView?m_pWebView->goBack():false;
- }
- bool CWkeWebkitUI::CanGoForward() const
- {
- return m_pWebView?m_pWebView->canGoForward():false;
- }
- bool CWkeWebkitUI::GoForward()
- {
- return m_pWebView?m_pWebView->goForward():false;
- }
- void CWkeWebkitUI::StopLoad()
- {
- if ( m_pWebView )
- m_pWebView->stopLoading();
- }
- void CWkeWebkitUI::Refresh()
- {
- if ( m_pWebView )
- {
- StopCheckThread();
- m_pWebView->reload();
- StartCheckThread();
- }
- }
- wkeWebView CWkeWebkitUI::GetWebView()
- {
- return m_pWebView;
- }
- void CWkeWebkitUI::SetLoadCallback( CWkeWebkitLoadCallback* pCallback )
- {
- m_pLoadCallback=pCallback;
- }
- CWkeWebkitLoadCallback* CWkeWebkitUI::GetLoadCallback()
- {
- return m_pLoadCallback;
- }
- void CWkeWebkitUI::OnTitleChange( const struct _wkeClientHandler* clientHandler, const wkeString title )
- {
- }
- void CWkeWebkitUI::OnUrlChange( const struct _wkeClientHandler* clientHandler, const wkeString url )
- {
- }
- void CWkeWebkitUI::LoadFile( LPCTSTR lpFile )
- {
- if ( m_pWebView )
- m_pWebView->loadFile(lpFile);
- }
- void CWkeWebkitUI::LoadHtml( LPCTSTR lpHtml )
- {
- if ( m_pWebView )
- m_pWebView->loadHTML(lpHtml);
- }
- const wstring& CWkeWebkitUI::GetUrl() const
- {
- return m_strUrl;
- }
- void CWkeWebkitUI::SetAttribute( LPCTSTR pstrName, LPCTSTR pstrValue )
- {
- if ( _tcscmp(pstrName, _T("url")) == 0 )
- m_strUrl = pstrValue;
- else
- CControlUI::SetAttribute(pstrName, pstrValue);
- }
- }
解析:
主要处理的就是消息部分,把这个区域的那种消息分发给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左右,也是开源的,大家可以网上看看。
版权声明:本文为博主原创文章,未经博主允许不得转载。(E-mail:jelinyao@163.com 新QQ群:515132477)
cctdbnj
疯狂-的-蜗牛
__Always
疯狂-的-蜗牛
__Always
疯狂-的-蜗牛
__Always
yangpu1209
疯狂-的-蜗牛
yangpu1209
BlueGhostFire
楼主window 里bktrans="true"时,webkit控件会锁死整个程序呢.
疯狂-的-蜗牛
yyf092220
yyf092220
edit标签无法正常切换。
请问select标签不能正常弹出是什么原因引起的
疯狂-的-蜗牛