由于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: jackliu100@gmail.com
*
* \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: jackliu100@gmail.com
*
* \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,妥妥的赞一个。

[原创]升级SOUI WKE以支持_blank的更多相关文章

  1. LNMP升级开启TLSv1.3支持

    LNMP升级开启TLSv1.3支持 TLSv1.3版本的优势:https://baijiahao.baidu.com/s?id=1611365293186683991&wfr=spider&a ...

  2. CentOS上升级gcc编译器使支持C++11

    首先向博主致敬,好的东西拿来共享了,用一下不错. https://blog.csdn.net/clirus/article/details/62424517 0. 目标  最近在学习c++11,我本机 ...

  3. (原创)linux下Microsoft/cpprestsdk支持https(server)

    原创,转载请标明源地址 之前看网上一堆的资料说Microsoft/cpprestsdk不支持https或者说只支持window下的https,差点就被误导了,没办法,只好自己去翻了下源代码 先说明下l ...

  4. 微服务架构 - Jimu(积木) 升级 1.0.0 支持 .Net Core 3.0

    如果不知道 Jimu(积木) 是啥,请移步 .Net Core 分布式微服务框架介绍 - Jimu 这次升级除了支持 .Net Core 3.0 还新增部分功能,如 REST, 链路跟踪等,以下为详细 ...

  5. Appserv环境下搭建的PHP环境升级PHP版本(支持微信端口以及thinkphp)

      Appserv 2.5.10 升级PHP from version 5.2 to 5.3 最近,在使用Appserv 2.5.10 中的PHP开发微信时,遇到下面错误 Fatal error  C ...

  6. [原创]-IIS7.5优化,支持同时10万个请求

    背景:        IIS7.5是微软推出的最新平台IIS,性能也较以前有很大的提升,但是默认的设置配不适合很大的请求.但是我们可以根据实际的需要进行IIS调整,使其性能更佳,支持同时10万个请求. ...

  7. PHPnow 升级后 PHP不支持GD、MySQL

    来自http://tunps.com/php-unsupport-gd-and-mysql-after-upgrade-phpnow 最近磁盘格式化误操作后,最近两天都在忙于数据恢复,现在才恢复正常. ...

  8. 原创:js代码, 让dedecms支持Tag选择, 添加内容更为方便,不用手输Tag

    dedecms在编辑修改内容时,TAG标签需要手动输,中文的Tag, 中间还得用半角字符','分隔,  输入法切来切去很不方便,   于是动手改后台代码, 利用后台的tags_main.php, 让d ...

  9. [原创]升级Gerrit的commit-msg,检查git commit时必须填写开发任务编号TaskID

    公司使用git+gerrit+jenkins进行持续集成实践,其中gerrit用来进行Code Review.另外我们自己研发了一套敏捷项目管理系统TPM(TeamPlus Management),用 ...

随机推荐

  1. 适配:px与dp转换

    public class DensityUtil { /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context con ...

  2. 洗碗机耗材:finish 亮碟 产品的选购

    转发&补充两点 1.亮碟在国内销售的洗涤块是最低端的Classic,二合一产品(理论上必须配合软水盐和亮碟剂).国外很早就淘汰掉Classic级的洗涤块了,当前最低端的是Advanced(四合 ...

  3. Nginx 之:nginx.conf结构

    nginx.conf文件结构如下: ..... events { ...... } http{ .... server{ .... } server{ listen  192.168.0.12:80; ...

  4. DOM笔录

    文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最为关心的是,DOM把 ...

  5. HTTP头的Expires与Cache-control区别

    2010年3月24日 a18ccms 发表评论 阅读评论 今天在群里聊天.说道了Expires.这里来说明下这两个的区别吧. 1.概念 Cache-control 用于控制HTTP缓存(在HTTP/1 ...

  6. PHP对全局变量_GET、_POST中特殊字符的过滤

     $sVariablesOrder = ini_get( 'variables_order' );      $request = array();      //过滤不安全数据   for ( $i ...

  7. python开发_python中的函数定义

    下面是我做的几个用列: #python中的函数定义,使用和传参 def_str = '''\ python中的函数以如下形式声明: def 函数名称([参数1,参数2,参数3......]): 执行语 ...

  8. C# Graphics中有关绘图质量的几个Mode

    一.CompositingMode 获取一个值,该值指定如何将合成图像绘制到此 Graphics.复合模式确定从源映像的像素是覆盖(SourceCopy)还是组合(SourceOver, 需要使用半透 ...

  9. C#并口操作

    using System;using System.Runtime.InteropServices;public class PortAccess { [DllImport("inpout3 ...

  10. subprocess in python3.5

    subprocess 该子模块允许你创建新的流程,连接到它们的输入/输出/错误管道,并获取他们的返回值.该模块打算替换多个旧的模块和功能:os.system   和  os.spawn * 使用sub ...