[原创]升级SOUI WKE以支持_blank
由于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了,哈哈哈。
直接上点干货
1 /*! 2 * \file SWkeWebkitEx.h 3 * \date 2016/04/12 14:31 4 * 5 * \author koangel 6 * Contact: jackliu100@gmail.com 7 * 8 * \brief 针对新版本WKE的封装,使用C函数版本 9 * 10 * 为了区分改为SWkeWbkitEx名,与之前版本不冲突。 11 */ 12 #pragma once 13 #include <wke.h> 14 15 #pragma comment(lib,"wke.lib") 16 17 namespace SOUI 18 { 19 // 此处改为自己渲染程序 20 class SWkeRenderGDI 21 { 22 public: 23 SWkeRenderGDI() 24 :m_hView(NULL) 25 , m_hDC(NULL) 26 , m_hBitmap(NULL) 27 , m_pixels(NULL) 28 , m_width(0) 29 , m_height(0) 30 { 31 } 32 33 virtual ~SWkeRenderGDI() 34 { 35 if (m_hDC) 36 DeleteDC(m_hDC); 37 38 if (m_hBitmap) 39 DeleteObject(m_hBitmap); 40 } 41 42 virtual bool init(HWND hView) 43 { 44 m_hView = hView; 45 m_hDC = CreateCompatibleDC(0); 46 47 RECT rect; 48 GetClientRect(hView, &rect); 49 resize(rect.right, rect.bottom); 50 return true; 51 } 52 53 virtual void destroy() 54 { 55 delete this; 56 } 57 58 virtual void resize(unsigned int w, unsigned int h) 59 { 60 if (m_width == w && m_height == h) 61 return; 62 63 m_width = w; 64 m_height = h; 65 m_pixels = NULL; 66 } 67 68 virtual void render(wkeWebView webView) 69 { 70 if (wkeIsDirty(webView)) 71 { 72 if (m_pixels == NULL) 73 createBitmap(); 74 75 wkePaint2(webView, m_pixels, 0); 76 77 HDC hDC = GetDC(m_hView); 78 BitBlt(hDC, 0, 0, m_width, m_height, m_hDC, 0, 0, SRCCOPY); 79 ReleaseDC(m_hView, hDC); 80 } 81 } 82 83 void createBitmap() 84 { 85 BITMAPINFO bi; 86 memset(&bi, 0, sizeof(bi)); 87 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 88 bi.bmiHeader.biWidth = int(m_width); 89 bi.bmiHeader.biHeight = -int(m_height); 90 bi.bmiHeader.biPlanes = 1; 91 bi.bmiHeader.biBitCount = 32; 92 bi.bmiHeader.biCompression = BI_RGB; 93 94 HBITMAP hbmp = ::CreateDIBSection(0, &bi, DIB_RGB_COLORS, &m_pixels, NULL, 0); 95 96 SelectObject(m_hDC, hbmp); 97 98 if (m_hBitmap) 99 DeleteObject(m_hBitmap); 100 101 m_hBitmap = hbmp; 102 } 103 104 private: 105 HWND m_hView; 106 HBITMAP m_hBitmap; 107 HDC m_hDC; 108 unsigned int m_width; 109 unsigned int m_height; 110 void* m_pixels; 111 }; 112 113 const char TM_TICKER = 1; 114 class SWkeWebkitEx : 115 public SWindow,protected IIdleHandler 116 { 117 SOUI_CLASS_NAME(SWkeWebkit, L"wkeWebkit") 118 public: 119 SWkeWebkitEx(); 120 virtual ~SWkeWebkitEx(); 121 122 // 初始化WKE 123 static void SWkeInit(); 124 // 销毁WKE 125 static void SWkeFinalize(); 126 127 wkeWebView GetWebView() { return m_pWebView; } 128 protected: 129 virtual BOOL OnIdle(); 130 protected: 131 int OnCreate(void *); 132 void OnDestroy(); 133 void OnPaint(IRenderTarget *pRT); 134 void OnSize(UINT nType, CSize size); 135 LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam); 136 LRESULT OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam); 137 LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam); 138 LRESULT OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam); 139 LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam); 140 LRESULT OnImeStartComposition(UINT uMsg, WPARAM wParam, LPARAM lParam); 141 void OnSetFocus(); 142 void OnKillFocus(); 143 void OnTimer(char cTimerID); 144 145 virtual BOOL OnSetCursor(const CPoint &pt); 146 virtual UINT OnGetDlgCode() { return SC_WANTALLKEYS; } 147 BOOL OnAttrUrl(SStringW strValue, BOOL bLoading); 148 SOUI_ATTRS_BEGIN() 149 ATTR_CUSTOM(L"url", OnAttrUrl) 150 SOUI_ATTRS_END() 151 152 SOUI_MSG_MAP_BEGIN() 153 MSG_WM_PAINT_EX(OnPaint) 154 MSG_WM_CREATE(OnCreate) 155 MSG_WM_DESTROY(OnDestroy) 156 MSG_WM_SIZE(OnSize) 157 MSG_WM_TIMER_EX(OnTimer) 158 MSG_WM_SETFOCUS_EX(OnSetFocus) 159 MSG_WM_KILLFOCUS_EX(OnKillFocus) 160 MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, 0x209, OnMouseEvent) 161 MESSAGE_HANDLER_EX(WM_MOUSEWHEEL, OnMouseWheel) 162 MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyDown) 163 MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyUp) 164 MESSAGE_HANDLER_EX(WM_CHAR, OnChar) 165 MESSAGE_HANDLER_EX(WM_IME_STARTCOMPOSITION, OnImeStartComposition) 166 SOUI_MSG_MAP_END() 167 protected: 168 wkeWebView m_pWebView; 169 SStringW m_strUrl; 170 SWkeRenderGDI m_render; 171 172 static wkeWebView onCreateView(wkeWebView webView, void* param, const wkeNewViewInfo* info); 173 }; 174 }
Cpp部分代码
1 /*! 2 * \file SWkeWebkitEx.cpp 3 * \date 2016/04/12 14:31 4 * 5 * \author koangel 6 * Contact: jackliu100@gmail.com 7 * 8 * \brief 针对新版本WKE的封装,使用C函数版本 9 * 10 * 为了区分改为SWkeWbkitEx名,与之前版本不冲突。 11 */ 12 #include "stdafx.h" 13 #include "SWkeWebkitEx.h" 14 #pragma comment(lib,"imm32.lib") 15 #pragma comment(lib,"msimg32.lib") 16 17 namespace SOUI 18 { 19 SWkeWebkitEx::SWkeWebkitEx() 20 { 21 SWkeInit(); // 如果需要请此处屏蔽(有多个WEBVIEW时) 22 m_pWebView = nullptr; 23 } 24 25 26 SWkeWebkitEx::~SWkeWebkitEx() 27 { 28 SWkeFinalize(); // 如果需要请此处屏蔽 29 } 30 31 void SWkeWebkitEx::SWkeInit() 32 { 33 wkeInitialize(); 34 } 35 36 void SWkeWebkitEx::SWkeFinalize() 37 { 38 wkeFinalize(); 39 } 40 41 BOOL SWkeWebkitEx::OnIdle() 42 { 43 m_render.render(m_pWebView); 44 InvalidateRect(NULL); 45 return TRUE; 46 } 47 48 49 int SWkeWebkitEx::OnCreate(void *) 50 { 51 m_pWebView = wkeCreateWebView(); 52 if (!m_pWebView) return 1; 53 54 HWND hWnd=GetContainer()->GetHostHwnd(); 55 56 m_render.init(hWnd); 57 58 wkeSetHostWindow(m_pWebView, hWnd); 59 wkeSetTransparent(m_pWebView, false); 60 wkeOnCreateView(m_pWebView, &SWkeWebkitEx::onCreateView, nullptr); 61 wkeSetUserAgent(m_pWebView, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); 62 wkeLoadURLW(m_pWebView,m_strUrl); 63 SetTimer(TM_TICKER,50); 64 return 0; 65 } 66 67 void SWkeWebkitEx::OnDestroy() 68 { 69 if (m_pWebView) 70 { 71 wkeDestroyWebView(m_pWebView); 72 m_pWebView = nullptr; 73 } 74 } 75 76 void SWkeWebkitEx::OnPaint(IRenderTarget *pRT) 77 { 78 CRect rcClip; 79 pRT->GetClipBox(&rcClip); 80 CRect rcClient; 81 GetClientRect(&rcClient); 82 CRect rcInvalid; 83 rcInvalid.IntersectRect(&rcClip, &rcClient); 84 HDC hdc = pRT->GetDC(); 85 HDC hWebviewHC = (HDC)wkeGetViewDC(m_pWebView); 86 if (GetStyle().m_byAlpha != 0xff) 87 { 88 BLENDFUNCTION bf = { AC_SRC_OVER,0,GetStyle().m_byAlpha,AC_SRC_ALPHA }; 89 AlphaBlend(hdc, rcInvalid.left, rcInvalid.top, rcInvalid.Width(), rcInvalid.Height(),hWebviewHC, rcInvalid.left - rcClient.left, rcInvalid.top - rcClient.top, rcInvalid.Width(), rcInvalid.Height(), bf); 90 } 91 else 92 { 93 BitBlt(hdc, rcInvalid.left, rcInvalid.top, rcInvalid.Width(), rcInvalid.Height(),hWebviewHC, rcInvalid.left - rcClient.left, rcInvalid.top - rcClient.top, SRCCOPY); 94 } 95 pRT->ReleaseDC(hdc); 96 } 97 98 void SWkeWebkitEx::OnSize(UINT nType, CSize size) 99 { 100 __super::OnSize(nType,size); 101 wkeResize(m_pWebView, size.cx, size.cy); 102 m_render.resize(size.cx, size.cy); 103 } 104 105 LRESULT SWkeWebkitEx::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) 106 { 107 if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN) 108 { 109 SetFocus(); 110 SetCapture(); 111 } 112 else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP || message == WM_RBUTTONUP) 113 { 114 ReleaseCapture(); 115 } 116 117 CRect rcClient; 118 GetClientRect(&rcClient); 119 120 int x = GET_X_LPARAM(lParam) - rcClient.left; 121 int y = GET_Y_LPARAM(lParam) - rcClient.top; 122 123 unsigned int flags = 0; 124 125 if (wParam & MK_CONTROL) 126 flags |= WKE_CONTROL; 127 if (wParam & MK_SHIFT) 128 flags |= WKE_SHIFT; 129 130 if (wParam & MK_LBUTTON) 131 flags |= WKE_LBUTTON; 132 if (wParam & MK_MBUTTON) 133 flags |= WKE_MBUTTON; 134 if (wParam & MK_RBUTTON) 135 flags |= WKE_RBUTTON; 136 137 bool bHandled = wkeFireMouseEvent(m_pWebView, message, x, y, flags); //m_pWebView->mouseEvent(message, x, y, flags); 138 SetMsgHandled(bHandled); 139 return 0; 140 } 141 142 LRESULT SWkeWebkitEx::OnMouseWheel(UINT uMsg, WPARAM wParam, LPARAM lParam) 143 { 144 POINT pt; 145 pt.x = GET_X_LPARAM(lParam); 146 pt.y = GET_Y_LPARAM(lParam); 147 HWND hWnd=GetContainer()->GetHostHwnd(); 148 ScreenToClient(hWnd, &pt); 149 150 int delta = GET_WHEEL_DELTA_WPARAM(wParam); 151 152 unsigned int flags = 0; 153 154 if (wParam & MK_CONTROL) 155 flags |= WKE_CONTROL; 156 if (wParam & MK_SHIFT) 157 flags |= WKE_SHIFT; 158 159 if (wParam & MK_LBUTTON) 160 flags |= WKE_LBUTTON; 161 if (wParam & MK_MBUTTON) 162 flags |= WKE_MBUTTON; 163 if (wParam & MK_RBUTTON) 164 flags |= WKE_RBUTTON; 165 166 167 bool bHandled = wkeFireMouseWheelEvent(m_pWebView, pt.x,pt.y,delta,flags); //m_pWebView->mouseEvent(message, x, y, flags); 168 SetMsgHandled(bHandled); 169 return 0; 170 } 171 172 LRESULT SWkeWebkitEx::OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam) 173 { 174 unsigned int virtualKeyCode = wParam; 175 unsigned int flags = 0; 176 if (HIWORD(lParam) & KF_REPEAT) 177 flags |= WKE_REPEAT; 178 if (HIWORD(lParam) & KF_EXTENDED) 179 flags |= WKE_EXTENDED; 180 181 bool handled = wkeFireKeyDownEvent(m_pWebView, virtualKeyCode, flags, false); 182 SetMsgHandled(handled); 183 return 0; 184 } 185 186 LRESULT SWkeWebkitEx::OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam) 187 { 188 unsigned int virtualKeyCode = wParam; 189 unsigned int flags = 0; 190 if (HIWORD(lParam) & KF_REPEAT) 191 flags |= WKE_REPEAT; 192 if (HIWORD(lParam) & KF_EXTENDED) 193 flags |= WKE_EXTENDED; 194 195 bool handled = wkeFireKeyUpEvent(m_pWebView, virtualKeyCode, flags, false); 196 SetMsgHandled(handled); 197 return 0; 198 } 199 200 LRESULT SWkeWebkitEx::OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam) 201 { 202 unsigned int charCode = wParam; 203 unsigned int flags = 0; 204 if (HIWORD(lParam) & KF_REPEAT) 205 flags |= WKE_REPEAT; 206 if (HIWORD(lParam) & KF_EXTENDED) 207 flags |= WKE_EXTENDED; 208 209 bool handled = wkeFireKeyPressEvent(m_pWebView, charCode, flags, false); 210 SetMsgHandled(handled); 211 return 0; 212 } 213 214 LRESULT SWkeWebkitEx::OnImeStartComposition(UINT uMsg, WPARAM wParam, LPARAM lParam) 215 { 216 wkeRect caret = wkeGetCaretRect(m_pWebView); 217 218 CRect rcClient; 219 GetClientRect(&rcClient); 220 221 CANDIDATEFORM form; 222 form.dwIndex = 0; 223 form.dwStyle = CFS_EXCLUDE; 224 form.ptCurrentPos.x = caret.x + rcClient.left; 225 form.ptCurrentPos.y = caret.y + caret.h + rcClient.top; 226 form.rcArea.top = caret.y + rcClient.top; 227 form.rcArea.bottom = caret.y + caret.h + rcClient.top; 228 form.rcArea.left = caret.x + rcClient.left; 229 form.rcArea.right = caret.x + caret.w + rcClient.left; 230 COMPOSITIONFORM compForm; 231 compForm.ptCurrentPos = form.ptCurrentPos; 232 compForm.rcArea = form.rcArea; 233 compForm.dwStyle = CFS_POINT; 234 235 HWND hWnd = GetContainer()->GetHostHwnd(); 236 HIMC hIMC = ImmGetContext(hWnd); 237 ImmSetCandidateWindow(hIMC, &form); 238 ImmSetCompositionWindow(hIMC, &compForm); 239 ImmReleaseContext(hWnd, hIMC); 240 241 return 0; 242 } 243 244 void SWkeWebkitEx::OnSetFocus() 245 { 246 wkeSetFocus(m_pWebView); 247 } 248 249 void SWkeWebkitEx::OnKillFocus() 250 { 251 wkeKillFocus(m_pWebView); 252 } 253 254 void SWkeWebkitEx::OnTimer(char cTimerID) 255 { 256 if (cTimerID == TM_TICKER) 257 { 258 m_render.render(m_pWebView); 259 InvalidateRect(NULL); 260 } 261 } 262 263 BOOL SWkeWebkitEx::OnSetCursor(const CPoint &pt) 264 { 265 return TRUE; 266 } 267 268 BOOL SWkeWebkitEx::OnAttrUrl(SStringW strValue, BOOL bLoading) 269 { 270 m_strUrl = strValue; 271 if (!bLoading) 272 wkeLoadURLW(m_pWebView,m_strUrl); 273 return !bLoading; 274 } 275 276 wkeWebView SWkeWebkitEx::onCreateView(wkeWebView webView, void* param, const wkeNewViewInfo* info) 277 { 278 const wchar_t* target = wkeGetStringW(info->target); 279 const wchar_t* url = wkeGetStringW(info->url); 280 281 if (wcscmp(target, L"") == 0 || wcscmp(target, L"_blank") == 0) 282 { 283 if (wcsnicmp(url, L"file:///", 8) == 0) 284 url += 8; 285 // 此处弹出其他程序运行指定内容 WKE代码部分 286 ShellExecuteW(NULL, L"open", (LPWSTR)url, NULL, NULL, SW_SHOW); 287 return NULL; 288 } 289 else if (wcscmp(target, L"_self") == 0) 290 { 291 return webView; 292 } 293 else if (wcscmp(target, L"wontOpen") == 0) 294 { 295 return NULL; 296 } 297 298 return webView; 299 } 300 301 }
对于Alert本人暂未测试,请稍后自行测试。
编译请使用海面宝宝同学的WKE,妥妥的赞一个。