miniblink 封装duilib 控件 WkeWebkitUI 离屏渲染方式

3 篇文章 0 订阅
1 篇文章 0 订阅

demo可以到github查看:https://github.com/zym479466697/duilib-miniblink.git

WkeWebkitUI.h

#ifndef __WKEWEBKIT__H_
#define __WKEWEBKIT__H_
#include <queue>
#include <Windows.h>
#include <objbase.h>
#include "..\..\DuiLib\UIlib.h"
using namespace DuiLib;

#include "./wke.h"
using namespace wke;

void LogFormat(const TCHAR* format, ...);

class IWkeEvent
{
public:
	//wke navigation callback
	virtual bool OnWkeNavigationCallback(wkeWebView webView, wkeNavigationType navigationType, const wkeString url) = 0;
	//wke loading callback
	virtual void OnWkeLoadingFinishCallback(wkeWebView webView, const wkeString url, wkeLoadingResult result, const wkeString failedReason) = 0;
	//wke title changed
	virtual void OnWkeTitleChanged(wkeWebView webView, const wkeString title) = 0;
	//wke url changed
	virtual void OnWkeUrlChanged(wkeWebView webView, const wkeString url) = 0;
};


class CWkeWebkitUI : 
	public CControlUI, 
	public IMessageFilterUI
{
public:
	CWkeWebkitUI(void);
	virtual ~CWkeWebkitUI(void);

	//init wke
	static void WkeWebkit_Init();
	//shutdown wke
	static void WkeWebkit_Shutdown();

	static void  OnWkeTitleChanged(wkeWebView webView, void* param, const wkeString title);
	static void  OnWkeUrlChanged(wkeWebView webView, void* param, const wkeString url);
	static void  OnWkeLoadingFinishCallback(wkeWebView webView, void* param, const wkeString url, wkeLoadingResult result, const wkeString failedReason);
	static bool  OnWkeNavigationCallback(wkeWebView webView, void* param, wkeNavigationType navigationType, const wkeString url);
	static void  OnWkePaintUpdatedCallback(wkeWebView webView, void* param, const HDC hdc, int x, int y, int cx, int cy);

	IWebView* GetWebView() { return m_pWebView;}
	//load url
	void LoadUrl(LPCTSTR pstrUrl);
	//load file
	void LoadFile(LPCTSTR pstrFile);
	//set wke event callback
	void SetWkeEvent(IWkeEvent* pWkeEvent);
	//run js
	jsValue RunJs(LPCTSTR pstrJs);
	//go back
	bool GoBack();
	//go forward
	bool GoForward();
protected:
	LPCTSTR GetClass() const;
	LPVOID GetInterface(LPCTSTR pstrName);
	void SetPos(RECT rc, bool bNeedInvalidate = true);
	void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
	bool DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl);
	virtual void DoInit();
	virtual LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled);
	
	bool OnMouseEvent( UINT message, WPARAM wParam,LPARAM lParam);
	bool OnKeyDown( UINT uMsg, WPARAM wParam,LPARAM lParam);
	bool OnKeyUp( UINT uMsg, WPARAM wParam,LPARAM lParam);
	bool OnMouseWheel( UINT uMsg, WPARAM wParam,LPARAM lParam);
	bool OnChar( UINT uMsg, WPARAM wParam,LPARAM lParam);
	bool OnContextMenu( UINT uMsg, WPARAM wParam,LPARAM lParam);
	bool OnImeStartComposition( UINT uMsg, WPARAM wParam,LPARAM lParam);
	bool OnSetCursor();

	//wke need paint
	void OnPaintUpdatedCallback(const HDC hdc, int x, int y, int cx, int cy);
private:
	IWebView* m_pWebView;
	DWORD m_byAlpha;
	IWkeEvent* m_pWkeEvent;
};

#endif /*__WKEWEBKIT__H_*/

WkeWebkitUI.cpp

#include "WkeWebkitUI.h"
#include <Imm.h>
#include <assert.h>
#pragma comment(lib,"imm32.lib")
#pragma comment(lib,"msimg32.lib")

void LogFormat(const TCHAR* format, ...)
{
	TCHAR szLog[4096] = {0};
	va_list arglist;
	va_start(arglist, format);
	_vsnwprintf_s(szLog, 4096, format, arglist);
	va_end(arglist);
	OutputDebugString(szLog);
	OutputDebugString(_T("\r\n"));
}

CWkeWebkitUI::CWkeWebkitUI(void) : m_byAlpha(255)
{
	m_pWebView = NULL;
	m_pWkeEvent = NULL;
}


CWkeWebkitUI::~CWkeWebkitUI(void)
{
	if(m_pWebView)
	{
		wkeDestroyWebView((wkeWebView)m_pWebView);
		m_pWebView = NULL;
	}
}

void CWkeWebkitUI::WkeWebkit_Init()
{
	wkeInit();
}

void CWkeWebkitUI::WkeWebkit_Shutdown()
{
	wkeShutdown();
}


LPCTSTR CWkeWebkitUI::GetClass() const
{
	return _T("wkeWebKit");
}

LPVOID CWkeWebkitUI::GetInterface(LPCTSTR pstrName)
{
	if( _tcscmp(pstrName, _T("wkeWebKit")) == 0 ) return static_cast<CWkeWebkitUI*>(this);
	return CControlUI::GetInterface(pstrName);
}

void CWkeWebkitUI::DoInit()
{
	CControlUI::DoInit();
	m_pWebView = (IWebView*)wkeCreateWebView();
	//wkeSetHandle((wkeWebView)m_pWebView, GetManager()->GetPaintWindow());
	//wkeSetTransparent((wkeWebView)m_pWebView, true);
	wkeOnTitleChanged((wkeWebView)m_pWebView, OnWkeTitleChanged, this);
	wkeOnURLChanged((wkeWebView)m_pWebView, OnWkeUrlChanged, this);
	wkeOnLoadingFinish((wkeWebView)m_pWebView,OnWkeLoadingFinishCallback,this);
	wkeOnNavigation((wkeWebView)m_pWebView, OnWkeNavigationCallback,this);
	wkeOnPaintUpdated((wkeWebView)m_pWebView, OnWkePaintUpdatedCallback,this);
	wkeSetUserAgent((wkeWebView)m_pWebView, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.2228.0 Safari/537.36");

	GetManager()->AddMessageFilter(this);
}

void CWkeWebkitUI::SetPos(RECT rc, bool bNeedInvalidate)
{
	CControlUI::SetPos(rc, bNeedInvalidate);

	if(m_pWebView) {
		m_pWebView->resize(rc.right - rc.left, rc.bottom - rc.top);
		//wkeRepaintIfNeeded((wkeWebView)m_pWebView);
	}
}


void CWkeWebkitUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
{
	if( _tcscmp(pstrName, _T("alpha")) == 0 ) {
		LPTSTR pstr = NULL;
		m_byAlpha = _tcstol(pstrValue, &pstr, 10);  ASSERT(pstr);
	}
	else
	{
		CControlUI::SetAttribute(pstrName, pstrValue);
	}
}

bool CWkeWebkitUI::DoPaint(HDC hDC, const RECT& rcPaint, CControlUI* pStopControl)
{
	if(!m_pWebView)
	{
		return CControlUI::DoPaint(hDC, rcPaint, pStopControl);
	}
	
	RECT rcClip;
	::GetClipBox(hDC, &rcClip);
	RECT rcClient = GetClientPos();
	RECT rcInvalid;
	::IntersectRect(&rcInvalid, &rcClip,&rcClient);
	int invalidWidth = rcInvalid.right - rcInvalid.left;
	int invalidHeight = rcInvalid.bottom - rcInvalid.top;
	HDC hdcWke = wkeGetViewDC((wkeWebView)m_pWebView);
	BOOL ret = false;
	if(m_byAlpha != 0xff)
	{
		BLENDFUNCTION bf = {AC_SRC_OVER, 0, m_byAlpha, AC_SRC_ALPHA };
		ret = AlphaBlend(hDC, rcInvalid.left, rcInvalid.top, invalidWidth, invalidHeight,
			hdcWke, rcInvalid.left-rcClient.left, rcInvalid.top-rcClient.top, invalidWidth, invalidHeight, bf);
	}
	else
	{
		ret = BitBlt(hDC, rcInvalid.left, rcInvalid.top, invalidWidth, invalidHeight,
			hdcWke, rcInvalid.left-rcClient.left, rcInvalid.top-rcClient.top,SRCCOPY);
	}
	return ret;
}


LRESULT CWkeWebkitUI::MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool& bHandled)
{
	bHandled = false;
	if (!IsVisible())
	{
		return 0;
	}
	switch(uMsg)
	{
	case WM_SETFOCUS:
		{
			if(m_pWebView) m_pWebView->setFocus();
		}break;
	case WM_KILLFOCUS:
		{
			if(m_pWebView) m_pWebView->killFocus();
		}break;
	case WM_KEYDOWN:
		{
			if(!IsFocused()) return false;
			bHandled = OnKeyDown(uMsg, wParam, lParam);
			return true;
		}break;
	case WM_KEYUP:
		{
			if(!IsFocused()) return false;
			bHandled = OnKeyUp(uMsg, wParam, lParam);
			return true;
		}break;
	case WM_CHAR:
		{
			if(!IsFocused()) return false;
			bHandled = OnChar(uMsg, wParam, lParam);
			return true;
		}break;
	case WM_IME_STARTCOMPOSITION:
		{
			bHandled = OnImeStartComposition(uMsg, wParam, lParam);
			return true;
		}break;
	case WM_CONTEXTMENU:
		{
			bHandled = OnContextMenu(uMsg, wParam, lParam);
			return true;
		}
		break;
	default:
		{
			if(uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
			{
				if(uMsg == WM_MOUSEHWHEEL || uMsg == WM_MOUSEWHEEL)
				{
					if(!IsFocused()) return false;
					bHandled = OnMouseWheel(uMsg, wParam, lParam);
				}
				else
				{
					bHandled = OnMouseEvent(uMsg, wParam, lParam);
				}
				return true;
			}
		}break;
	}
	return false;
}

void CWkeWebkitUI::LoadUrl(LPCTSTR pstrUrl)
{
	m_pWebView->loadURL(pstrUrl);
}

void CWkeWebkitUI::LoadFile(LPCTSTR pstrFile)
{
	m_pWebView->loadFile(pstrFile);
}

void CWkeWebkitUI::SetWkeEvent(IWkeEvent* pWkeEvent)
{
	m_pWkeEvent = pWkeEvent;
}

jsValue CWkeWebkitUI::RunJs(LPCTSTR pstrJs)
{
	return m_pWebView->runJS(pstrJs);
}

bool CWkeWebkitUI::GoBack()
{
	return m_pWebView->goBack();
}

bool CWkeWebkitUI::GoForward()
{
	return m_pWebView->goForward();
}

bool CWkeWebkitUI::OnMouseEvent( UINT message, WPARAM wParam,LPARAM lParam)
{
	RECT rcClient = GetClientPos();
	POINT point = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
	if(!PtInRect(&rcClient, point))
	{
		if (message == WM_LBUTTONDOWN 
			|| message == WM_MBUTTONDOWN 
			|| message == WM_RBUTTONDOWN)
		{
			m_bFocused = false;
		}
		return false;
	}
	
	int x = GET_X_LPARAM(lParam)-rcClient.left;
	int y = GET_Y_LPARAM(lParam)-rcClient.top;

	if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN)
	{
		SetFocus();
		GetManager()->SetCapture();
	}
	else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP || message == WM_RBUTTONUP)
	{
		GetManager()->ReleaseCapture();
	}
	
	unsigned int flags = 0;

	if (wParam & MK_CONTROL)
		flags |= WKE_CONTROL;
	if (wParam & MK_SHIFT)
		flags |= WKE_SHIFT;

	if (wParam & MK_LBUTTON)
		flags |= WKE_LBUTTON;
	if (wParam & MK_MBUTTON)
		flags |= WKE_MBUTTON;
	if (wParam & MK_RBUTTON)
		flags |= WKE_RBUTTON;

	bool bHandled = m_pWebView->fireMouseEvent(message, x, y, flags);

	OnSetCursor();
	return bHandled;
}

bool CWkeWebkitUI::OnKeyDown( UINT uMsg, WPARAM wParam,LPARAM lParam )
{
	unsigned int flags = 0;
	if (HIWORD(lParam) & KF_REPEAT)
		flags |= WKE_REPEAT;
	if (HIWORD(lParam) & KF_EXTENDED)
		flags |= WKE_EXTENDED;

	bool bHandled = m_pWebView->fireKeyDownEvent(wParam, flags, false);
	return bHandled;
}

bool CWkeWebkitUI::OnKeyUp( UINT uMsg, WPARAM wParam,LPARAM lParam)
{
	unsigned int flags = 0;
	if (HIWORD(lParam) & KF_REPEAT)
		flags |= WKE_REPEAT;
	if (HIWORD(lParam) & KF_EXTENDED)
		flags |= WKE_EXTENDED;

	bool bHandled = m_pWebView->fireKeyUpEvent(wParam, flags, false);
	return bHandled;
}

bool CWkeWebkitUI::OnMouseWheel( UINT uMsg, WPARAM wParam,LPARAM lParam )
{
	POINT pt;
	pt.x = GET_X_LPARAM(lParam);
	pt.y = GET_Y_LPARAM(lParam);

	RECT rc = GetClientPos();
	pt.x -= rc.left;
	pt.y -= rc.top;

	int delta = GET_WHEEL_DELTA_WPARAM(wParam);

	unsigned int flags = 0;

	if (wParam & MK_CONTROL)
		flags |= WKE_CONTROL;
	if (wParam & MK_SHIFT)
		flags |= WKE_SHIFT;

	if (wParam & MK_LBUTTON)
		flags |= WKE_LBUTTON;
	if (wParam & MK_MBUTTON)
		flags |= WKE_MBUTTON;
	if (wParam & MK_RBUTTON)
		flags |= WKE_RBUTTON;

	//flags = wParam;

	bool bHandled = m_pWebView->fireMouseWheelEvent(pt.x, pt.y, delta, flags);
	return bHandled;
}

bool CWkeWebkitUI::OnChar( UINT uMsg, WPARAM wParam,LPARAM lParam )
{
	unsigned int charCode = wParam;
	unsigned int flags = 0;
	if (HIWORD(lParam) & KF_REPEAT)
		flags |= WKE_REPEAT;
	if (HIWORD(lParam) & KF_EXTENDED)
		flags |= WKE_EXTENDED;

	//flags = HIWORD(lParam);

	bool bHandled = m_pWebView->fireKeyPressEvent(wParam, flags, false);
	return bHandled;
}

bool CWkeWebkitUI::OnContextMenu( UINT uMsg, WPARAM wParam,LPARAM lParam)
{
	POINT pt;
	pt.x = GET_X_LPARAM(lParam);
	pt.y = GET_Y_LPARAM(lParam);

	if (pt.x != -1 && pt.y != -1)
		ScreenToClient(GetManager()->GetPaintWindow(), &pt);

	unsigned int flags = 0;
	if (wParam & MK_CONTROL)
		flags |= WKE_CONTROL;
	if (wParam & MK_SHIFT)
		flags |= WKE_SHIFT;

	if (wParam & MK_LBUTTON)
		flags |= WKE_LBUTTON;
	if (wParam & MK_MBUTTON)
		flags |= WKE_MBUTTON;
	if (wParam & MK_RBUTTON)
		flags |= WKE_RBUTTON;
	bool bHandled = m_pWebView->fireContextMenuEvent(pt.x, pt.y, flags);
	return bHandled;
}

bool CWkeWebkitUI::OnImeStartComposition( UINT uMsg, WPARAM wParam,LPARAM lParam )
{
	wkeRect caret = m_pWebView->getCaret();

	RECT rcClient = GetClientPos();

	CANDIDATEFORM form;
	form.dwIndex = 0;
	form.dwStyle = CFS_EXCLUDE;
	form.ptCurrentPos.x = caret.x + rcClient.left;
	form.ptCurrentPos.y = caret.y + caret.h + rcClient.top;
	form.rcArea.top = caret.y + rcClient.top;
	form.rcArea.bottom = caret.y + caret.h + rcClient.top;
	form.rcArea.left = caret.x + rcClient.left;
	form.rcArea.right = caret.x + caret.w + rcClient.left;
	COMPOSITIONFORM compForm;
	compForm.ptCurrentPos=form.ptCurrentPos;
	compForm.rcArea=form.rcArea;
	compForm.dwStyle=CFS_POINT;

	HWND hWnd=GetManager()->GetPaintWindow();
	HIMC hIMC = ImmGetContext(hWnd);
	ImmSetCandidateWindow(hIMC, &form);
	ImmSetCompositionWindow(hIMC,&compForm);
	ImmReleaseContext(hWnd, hIMC);
	return true;
}

bool CWkeWebkitUI::OnSetCursor()
{
	int cursorInfoType = wkeGetCursorInfoType((wkeWebView)m_pWebView);
	HCURSOR hCur = NULL;
	switch (cursorInfoType) {
	case WkeCursorInfoPointer:
		hCur = ::LoadCursor(NULL, IDC_ARROW);
		break;
	case WkeCursorInfoIBeam:
		hCur = ::LoadCursor(NULL, IDC_IBEAM);
		break;
	case WkeCursorInfoHand:
		hCur = ::LoadCursor(NULL, IDC_HAND);
		break;
	case WkeCursorInfoWait:
		hCur = ::LoadCursor(NULL, IDC_WAIT);
		break;
	case WkeCursorInfoHelp:
		hCur = ::LoadCursor(NULL, IDC_HELP);
		break;
	case WkeCursorInfoEastResize:
		hCur = ::LoadCursor(NULL, IDC_SIZEWE);
		break;
	case WkeCursorInfoNorthResize:
		hCur = ::LoadCursor(NULL, IDC_SIZENS);
		break;
	case WkeCursorInfoSouthWestResize:
	case WkeCursorInfoNorthEastResize:
		hCur = ::LoadCursor(NULL, IDC_SIZENESW);
		break;
	case WkeCursorInfoSouthResize:
	case WkeCursorInfoNorthSouthResize:
		hCur = ::LoadCursor(NULL, IDC_SIZENS);
		break;
	case WkeCursorInfoNorthWestResize:
	case WkeCursorInfoSouthEastResize:
		hCur = ::LoadCursor(NULL, IDC_SIZENWSE);
		break;
	case WkeCursorInfoWestResize:
	case WkeCursorInfoEastWestResize:
		hCur = ::LoadCursor(NULL, IDC_SIZEWE);
		break;
	case WkeCursorInfoNorthEastSouthWestResize:
	case WkeCursorInfoNorthWestSouthEastResize:
		hCur = ::LoadCursor(NULL, IDC_SIZEALL);
		break;
	default:
		hCur = ::LoadCursor(NULL, IDC_ARROW);
		break;
	}

	if (hCur) {
		::SetCursor(hCur);
		return true;
	}
	return false;
}


void CWkeWebkitUI::OnWkeTitleChanged(wkeWebView webView, void* param, const wkeString title)
{
	CWkeWebkitUI* pWkeUI =(CWkeWebkitUI*)param;
	IWebView* pWebView = (IWebView*)webView;
	if(pWkeUI && pWkeUI->m_pWkeEvent)
	{
		pWkeUI->m_pWkeEvent->OnWkeTitleChanged(webView, title);
	}
}

void CWkeWebkitUI::OnWkeUrlChanged(wkeWebView webView, void* param, const wkeString url)
{
	CWkeWebkitUI* pWkeUI =(CWkeWebkitUI*)param;
	IWebView* pWebView = (IWebView*)webView;
	if(pWkeUI && pWkeUI->m_pWkeEvent)
	{
		pWkeUI->m_pWkeEvent->OnWkeUrlChanged(webView, url);
	}
}

void CWkeWebkitUI::OnWkeLoadingFinishCallback(wkeWebView webView, void* param, const wkeString url, wkeLoadingResult result, const wkeString failedReason)
{
	CWkeWebkitUI* pWkeUI =(CWkeWebkitUI*)param;
	IWebView* pWebView = (IWebView*)webView;
	if(pWkeUI && pWkeUI->m_pWkeEvent)
	{
		pWkeUI->m_pWkeEvent->OnWkeLoadingFinishCallback(webView, url, result, failedReason);
	}
}


bool  CWkeWebkitUI::OnWkeNavigationCallback(wkeWebView webView, void* param, wkeNavigationType navigationType, const wkeString url)
{
	CWkeWebkitUI* pWkeUI =(CWkeWebkitUI*)param;
	IWebView* pWebView = (IWebView*)webView;
	if(pWkeUI && pWkeUI->m_pWkeEvent)
	{
		return pWkeUI->m_pWkeEvent->OnWkeNavigationCallback(webView, navigationType, url);
	}
	return true;
}


void CWkeWebkitUI::OnWkePaintUpdatedCallback(wkeWebView webView, void* param, const HDC hdc, int x, int y, int cx, int cy)
{
	CWkeWebkitUI* pWkeUI =(CWkeWebkitUI*)param;
	IWebView* pWebView = (IWebView*)webView;
	if(pWkeUI && pWebView == pWkeUI->m_pWebView)
	{
		pWkeUI->OnPaintUpdatedCallback(hdc, x,y,cx,cy);
	}
}

void CWkeWebkitUI::OnPaintUpdatedCallback(const HDC hdc, int x, int y, int cx, int cy)
{
	//RECT invalidateRc = {x, y, cx, cy};
	//if( m_pManager != NULL ) m_pManager->Invalidate(invalidateRc);
	Invalidate();
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值