由于WKE的精简模式,导致原有的SOUI不支持针对诸多内容的调用,此处针对WKE的部分内容做升级,以支持对应的功能。

目的:使WKE可以_blank弹出新窗口。

由国人 海绵宝宝维护的WKE新分支:https://github.com/cexer/wke

编译新WKE的方式很简单:

1、下载master,并解压缩,如果有git就自己clone一下就好了

2、运行根目录下的vs2008.bat,打开后直接编译即可,时间根据CPU不同而不同。

SOUI的模式是动态加载函数,所以参考一下WKE头文件,即可完成函数调用。

特别注意,SOUI的WKE.DLL中已经将WKE封装为类,此处的WKE.DLL内是纯C函数,无类,所以我们要自己写。

如果懒得自己写动态接口,就直接引用WKE.H就好了,然后连接一下WKE.LIB(这样只是不太好剥离或按目录加载库)。

由于本人巨懒,懒癌晚期,所以我直接引用lib了,哈哈哈。

直接上点干货

 /*!
* \file SWkeWebkitEx.h
* \date 2016/04/12 14:31
*
* \author koangel
* Contact: [email protected]
*
* \brief 针对新版本WKE的封装,使用C函数版本
*
* 为了区分改为SWkeWbkitEx名,与之前版本不冲突。
*/
#pragma once
#include <wke.h> #pragma comment(lib,"wke.lib") namespace SOUI
{
// 此处改为自己渲染程序
class SWkeRenderGDI
{
public:
SWkeRenderGDI()
:m_hView(NULL)
, m_hDC(NULL)
, m_hBitmap(NULL)
, m_pixels(NULL)
, m_width()
, m_height()
{
} virtual ~SWkeRenderGDI()
{
if (m_hDC)
DeleteDC(m_hDC); if (m_hBitmap)
DeleteObject(m_hBitmap);
} virtual bool init(HWND hView)
{
m_hView = hView;
m_hDC = CreateCompatibleDC(); RECT rect;
GetClientRect(hView, &rect);
resize(rect.right, rect.bottom);
return true;
} virtual void destroy()
{
delete this;
} virtual void resize(unsigned int w, unsigned int h)
{
if (m_width == w && m_height == h)
return; m_width = w;
m_height = h;
m_pixels = NULL;
} virtual void render(wkeWebView webView)
{
if (wkeIsDirty(webView))
{
if (m_pixels == NULL)
createBitmap(); wkePaint2(webView, m_pixels, ); HDC hDC = GetDC(m_hView);
BitBlt(hDC, , , m_width, m_height, m_hDC, , , SRCCOPY);
ReleaseDC(m_hView, hDC);
}
} void createBitmap()
{
BITMAPINFO bi;
memset(&bi, , sizeof(bi));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = int(m_width);
bi.bmiHeader.biHeight = -int(m_height);
bi.bmiHeader.biPlanes = ;
bi.bmiHeader.biBitCount = ;
bi.bmiHeader.biCompression = BI_RGB; HBITMAP hbmp = ::CreateDIBSection(, &bi, DIB_RGB_COLORS, &m_pixels, NULL, ); SelectObject(m_hDC, hbmp); if (m_hBitmap)
DeleteObject(m_hBitmap); m_hBitmap = hbmp;
} private:
HWND m_hView;
HBITMAP m_hBitmap;
HDC m_hDC;
unsigned int m_width;
unsigned int m_height;
void* m_pixels;
}; const char TM_TICKER = ;
class SWkeWebkitEx :
public SWindow,protected IIdleHandler
{
SOUI_CLASS_NAME(SWkeWebkit, L"wkeWebkit")
public:
SWkeWebkitEx();
virtual ~SWkeWebkitEx(); // 初始化WKE
static void SWkeInit();
// 销毁WKE
static void SWkeFinalize(); wkeWebView GetWebView() { return m_pWebView; }
protected:
virtual BOOL OnIdle();
protected:
int OnCreate(void *);
void OnDestroy();
void OnPaint(IRenderTarget *pRT);
void OnSize(UINT nType, CSize size);
LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT OnImeStartComposition(UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnSetFocus();
void OnKillFocus();
void OnTimer(char cTimerID); virtual BOOL OnSetCursor(const CPoint &pt);
virtual UINT OnGetDlgCode() { return SC_WANTALLKEYS; }
BOOL OnAttrUrl(SStringW strValue, BOOL bLoading);
SOUI_ATTRS_BEGIN()
ATTR_CUSTOM(L"url", OnAttrUrl)
SOUI_ATTRS_END() SOUI_MSG_MAP_BEGIN()
MSG_WM_PAINT_EX(OnPaint)
MSG_WM_CREATE(OnCreate)
MSG_WM_DESTROY(OnDestroy)
MSG_WM_SIZE(OnSize)
MSG_WM_TIMER_EX(OnTimer)
MSG_WM_SETFOCUS_EX(OnSetFocus)
MSG_WM_KILLFOCUS_EX(OnKillFocus)
MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, 0x209, OnMouseEvent)
MESSAGE_HANDLER_EX(WM_MOUSEWHEEL, OnMouseWheel)
MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyDown)
MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyUp)
MESSAGE_HANDLER_EX(WM_CHAR, OnChar)
MESSAGE_HANDLER_EX(WM_IME_STARTCOMPOSITION, OnImeStartComposition)
SOUI_MSG_MAP_END()
protected:
wkeWebView m_pWebView;
SStringW m_strUrl;
SWkeRenderGDI m_render; static wkeWebView onCreateView(wkeWebView webView, void* param, const wkeNewViewInfo* info);
};
}

Cpp部分代码

 /*!
* \file SWkeWebkitEx.cpp
* \date 2016/04/12 14:31
*
* \author koangel
* Contact: [email protected]
*
* \brief 针对新版本WKE的封装,使用C函数版本
*
* 为了区分改为SWkeWbkitEx名,与之前版本不冲突。
*/
#include "stdafx.h"
#include "SWkeWebkitEx.h"
#pragma comment(lib,"imm32.lib")
#pragma comment(lib,"msimg32.lib") namespace SOUI
{
SWkeWebkitEx::SWkeWebkitEx()
{
SWkeInit(); // 如果需要请此处屏蔽(有多个WEBVIEW时)
m_pWebView = nullptr;
} SWkeWebkitEx::~SWkeWebkitEx()
{
SWkeFinalize(); // 如果需要请此处屏蔽
} void SWkeWebkitEx::SWkeInit()
{
wkeInitialize();
} void SWkeWebkitEx::SWkeFinalize()
{
wkeFinalize();
} BOOL SWkeWebkitEx::OnIdle()
{
m_render.render(m_pWebView);
InvalidateRect(NULL);
return TRUE;
} int SWkeWebkitEx::OnCreate(void *)
{
m_pWebView = wkeCreateWebView();
if (!m_pWebView) return ; HWND hWnd=GetContainer()->GetHostHwnd(); m_render.init(hWnd); wkeSetHostWindow(m_pWebView, hWnd);
wkeSetTransparent(m_pWebView, false);
wkeOnCreateView(m_pWebView, &SWkeWebkitEx::onCreateView, nullptr);
wkeSetUserAgent(m_pWebView, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
wkeLoadURLW(m_pWebView,m_strUrl);
SetTimer(TM_TICKER,);
return ;
} void SWkeWebkitEx::OnDestroy()
{
if (m_pWebView)
{
wkeDestroyWebView(m_pWebView);
m_pWebView = nullptr;
}
} void SWkeWebkitEx::OnPaint(IRenderTarget *pRT)
{
CRect rcClip;
pRT->GetClipBox(&rcClip);
CRect rcClient;
GetClientRect(&rcClient);
CRect rcInvalid;
rcInvalid.IntersectRect(&rcClip, &rcClient);
HDC hdc = pRT->GetDC();
HDC hWebviewHC = (HDC)wkeGetViewDC(m_pWebView);
if (GetStyle().m_byAlpha != 0xff)
{
BLENDFUNCTION bf = { AC_SRC_OVER,,GetStyle().m_byAlpha,AC_SRC_ALPHA };
AlphaBlend(hdc, rcInvalid.left, rcInvalid.top, rcInvalid.Width(), rcInvalid.Height(),hWebviewHC, rcInvalid.left - rcClient.left, rcInvalid.top - rcClient.top, rcInvalid.Width(), rcInvalid.Height(), bf);
}
else
{
BitBlt(hdc, rcInvalid.left, rcInvalid.top, rcInvalid.Width(), rcInvalid.Height(),hWebviewHC, rcInvalid.left - rcClient.left, rcInvalid.top - rcClient.top, SRCCOPY);
}
pRT->ReleaseDC(hdc);
} void SWkeWebkitEx::OnSize(UINT nType, CSize size)
{
__super::OnSize(nType,size);
wkeResize(m_pWebView, size.cx, size.cy);
m_render.resize(size.cx, size.cy);
} LRESULT SWkeWebkitEx::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN)
{
SetFocus();
SetCapture();
}
else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP || message == WM_RBUTTONUP)
{
ReleaseCapture();
} CRect rcClient;
GetClientRect(&rcClient); int x = GET_X_LPARAM(lParam) - rcClient.left;
int y = GET_Y_LPARAM(lParam) - rcClient.top; unsigned int flags = ; 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 = wkeFireMouseEvent(m_pWebView, message, x, y, flags); //m_pWebView->mouseEvent(message, x, y, flags);
SetMsgHandled(bHandled);
return ;
} LRESULT SWkeWebkitEx::OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
HWND hWnd=GetContainer()->GetHostHwnd();
ScreenToClient(hWnd, &pt); int delta = GET_WHEEL_DELTA_WPARAM(wParam); unsigned int flags = ; 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 = wkeFireMouseWheelEvent(m_pWebView, pt.x,pt.y,delta,flags); //m_pWebView->mouseEvent(message, x, y, flags);
SetMsgHandled(bHandled);
return ;
} LRESULT SWkeWebkitEx::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
unsigned int virtualKeyCode = wParam;
unsigned int flags = ;
if (HIWORD(lParam) & KF_REPEAT)
flags |= WKE_REPEAT;
if (HIWORD(lParam) & KF_EXTENDED)
flags |= WKE_EXTENDED; bool handled = wkeFireKeyDownEvent(m_pWebView, virtualKeyCode, flags, false);
SetMsgHandled(handled);
return ;
} LRESULT SWkeWebkitEx::OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
unsigned int virtualKeyCode = wParam;
unsigned int flags = ;
if (HIWORD(lParam) & KF_REPEAT)
flags |= WKE_REPEAT;
if (HIWORD(lParam) & KF_EXTENDED)
flags |= WKE_EXTENDED; bool handled = wkeFireKeyUpEvent(m_pWebView, virtualKeyCode, flags, false);
SetMsgHandled(handled);
return ;
} LRESULT SWkeWebkitEx::OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
unsigned int charCode = wParam;
unsigned int flags = ;
if (HIWORD(lParam) & KF_REPEAT)
flags |= WKE_REPEAT;
if (HIWORD(lParam) & KF_EXTENDED)
flags |= WKE_EXTENDED; bool handled = wkeFireKeyPressEvent(m_pWebView, charCode, flags, false);
SetMsgHandled(handled);
return ;
} LRESULT SWkeWebkitEx::OnImeStartComposition(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
wkeRect caret = wkeGetCaretRect(m_pWebView); CRect rcClient;
GetClientRect(&rcClient); CANDIDATEFORM form;
form.dwIndex = ;
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 = GetContainer()->GetHostHwnd();
HIMC hIMC = ImmGetContext(hWnd);
ImmSetCandidateWindow(hIMC, &form);
ImmSetCompositionWindow(hIMC, &compForm);
ImmReleaseContext(hWnd, hIMC); return ;
} void SWkeWebkitEx::OnSetFocus()
{
wkeSetFocus(m_pWebView);
} void SWkeWebkitEx::OnKillFocus()
{
wkeKillFocus(m_pWebView);
} void SWkeWebkitEx::OnTimer(char cTimerID)
{
if (cTimerID == TM_TICKER)
{
m_render.render(m_pWebView);
InvalidateRect(NULL);
}
} BOOL SWkeWebkitEx::OnSetCursor(const CPoint &pt)
{
return TRUE;
} BOOL SWkeWebkitEx::OnAttrUrl(SStringW strValue, BOOL bLoading)
{
m_strUrl = strValue;
if (!bLoading)
wkeLoadURLW(m_pWebView,m_strUrl);
return !bLoading;
} wkeWebView SWkeWebkitEx::onCreateView(wkeWebView webView, void* param, const wkeNewViewInfo* info)
{
const wchar_t* target = wkeGetStringW(info->target);
const wchar_t* url = wkeGetStringW(info->url); if (wcscmp(target, L"") == || wcscmp(target, L"_blank") == )
{
if (wcsnicmp(url, L"file:///", ) == )
url += ;
// 此处弹出其他程序运行指定内容 WKE代码部分
ShellExecuteW(NULL, L"open", (LPWSTR)url, NULL, NULL, SW_SHOW);
return NULL;
}
else if (wcscmp(target, L"_self") == )
{
return webView;
}
else if (wcscmp(target, L"wontOpen") == )
{
return NULL;
} return webView;
} }

对于Alert本人暂未测试,请稍后自行测试。

编译请使用海面宝宝同学的WKE,妥妥的赞一个。

04-24 21:26