add simple implement of WebView for win32

1.add simple implement of WebView for win32
2.Modify `std::string' to `const std::string &' as issues 7958 said
3.Open the test case in cpp-tests
This commit is contained in:
Jeff 2014-09-17 22:30:15 +08:00
parent 721311f106
commit 27919dad77
8 changed files with 928 additions and 11 deletions

View File

@ -28,5 +28,9 @@
#include "UIWebViewImpl-android.h" #include "UIWebViewImpl-android.h"
#include "UIWebView-inl.h" #include "UIWebView-inl.h"
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "UIWebViewImpl_win32.h"
#include "UIWebView-inl.h"
#endif #endif

View File

@ -25,7 +25,9 @@
#ifndef __COCOS2D_UI_WEBVIEW_H #ifndef __COCOS2D_UI_WEBVIEW_H
#define __COCOS2D_UI_WEBVIEW_H #define __COCOS2D_UI_WEBVIEW_H
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) #include "platform/CCPlatformConfig.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "ui/UIWidget.h" #include "ui/UIWidget.h"
@ -129,7 +131,7 @@ public:
virtual void setVisible(bool visible) override; virtual void setVisible(bool visible) override;
typedef std::function<void(WebView *sender, std::string url)> ccWebViewCallbak; typedef std::function<void(WebView *sender, const std::string &url)> ccWebViewCallbak;
/** /**
@ -138,7 +140,7 @@ public:
* @param url content URL. * @param url content URL.
* @return YES if the web view should begin loading content; otherwise, NO . * @return YES if the web view should begin loading content; otherwise, NO .
*/ */
void setOnShouldStartLoading(const std::function<bool(WebView *sender, std::string url)>& callback); void setOnShouldStartLoading(const std::function<bool(WebView *sender, const std::string &url)>& callback);
/** /**
* Call after a web view finishes loading. * Call after a web view finishes loading.
@ -159,7 +161,7 @@ public:
*/ */
void setOnJSCallback(const ccWebViewCallbak& callback); void setOnJSCallback(const ccWebViewCallbak& callback);
std::function<bool(WebView *sender, std::string url)> getOnShouldStartLoading()const; std::function<bool(WebView *sender, const std::string &url)> getOnShouldStartLoading()const;
ccWebViewCallbak getOnDidFinishLoading()const; ccWebViewCallbak getOnDidFinishLoading()const;
ccWebViewCallbak getOnDidFailLoading()const; ccWebViewCallbak getOnDidFailLoading()const;
ccWebViewCallbak getOnJSCallback()const; ccWebViewCallbak getOnJSCallback()const;
@ -168,7 +170,7 @@ protected:
virtual cocos2d::ui::Widget* createCloneInstance() override; virtual cocos2d::ui::Widget* createCloneInstance() override;
virtual void copySpecialProperties(Widget* model) override; virtual void copySpecialProperties(Widget* model) override;
std::function<bool(WebView *sender, std::string url)> _onShouldStartLoading; std::function<bool(WebView *sender, const std::string &url)> _onShouldStartLoading;
ccWebViewCallbak _onDidFinishLoading; ccWebViewCallbak _onDidFinishLoading;

View File

@ -0,0 +1,838 @@
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include <atlbase.h>
#include <atlwin.h>
#include <ExDispid.h>
#include <UrlMon.h>
#include "UIWebViewImpl_win32.h"
#include "UIWebView.h"
#include "base/CCDirector.h"
#include "platform/CCFileUtils.h"
#include "platform/CCGLView.h"
class Win32WebControl : public DWebBrowserEvents2
{
public:
Win32WebControl();
bool createWebView(
const std::function<bool (const std::string &)> &shouldStartLoading,
const std::function<void (const std::string &)> &didFinishLoading,
const std::function<void (const std::string &)> &didFailLoading,
const std::function<void (const std::string &)> &onJsCallback);
void removeWebView();
void setWebViewRect(const int left, const int top, const int width, const int height);
void setJavascriptInterfaceScheme(const std::string &scheme) const;
void loadData(const std::string &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL) const;
void loadHTMLString(const std::string &html, const std::string &baseURL);
void loadUrl(const std::string &url) const;
void loadFile(const std::string &filePath) const;
void stopLoading() const;
void reload() const;
bool canGoBack() const;
bool canGoForward() const;
void goBack() const;
void goForward() const;
void evaluateJS(const std::string &js) const;
void setScalesPageToFit(const bool scalesPageToFit) const;
void setWebViewVisible(const bool visible) const;
// Implement IUnknown
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
// Implement IDispatch
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo);
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
REFIID riid,
LPOLESTR *rgszNames,
UINT cNames,
LCID lcid,
DISPID *rgDispId);
virtual HRESULT STDMETHODCALLTYPE Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr);
private:
CAxWindow _winContainer;
IWebBrowser2 *_webBrowser2;
IConnectionPoint *_connectionPoint;
IDispatch *_htmlDoc;
bool _goBackEnabled;
bool _goForwardEnabled;
DWORD _cookie;
ULONG _reference;
std::function<bool (const std::string &)> _shouldStartLoading;
std::function<void (const std::string &)> _didFinishLoading;
std::function<void (const std::string &)> _didFailLoading;
std::function<void (const std::string &)> _onJsCallback;
std::string _htmlWillLoad;
static bool s_isInitialized;
static CComModule s_module;
static void lazyInit();
void _loadHTMLString(const std::string &html) const;
void loadUrl(BSTR url) const;
void loadUrl(const std::wstring &url) const;
};
namespace cocos2d {
namespace experimental {
namespace ui {
WebViewImpl::WebViewImpl(WebView *webView) : _createSucceeded(false), _systemWebControl(nullptr), _webView(webView)
{
_systemWebControl = new Win32WebControl();
if (_systemWebControl == nullptr)
{
return;
}
_createSucceeded = _systemWebControl->createWebView(
[this](const std::string &url)->bool {
if (_webView->shouldStartLoading != nullptr)
{
return _webView->shouldStartLoading(_webView, url);
}
return true;
},
[this](const std::string &url) {
if (_webView->didFinishLoading != nullptr)
{
_webView->didFinishLoading(_webView, url);
}
},
[this](const std::string &url) {
if (_webView->didFailLoading != nullptr)
{
_webView->didFailLoading(_webView, url);
}
},
[this](const std::string &url) {
if (_webView->onJsCallback != nullptr)
{
_webView->onJsCallback(_webView, url);
}
});
}
WebViewImpl::~WebViewImpl()
{
if (_systemWebControl != nullptr)
{
_systemWebControl->removeWebView();
delete _systemWebControl;
_systemWebControl = nullptr;
}
}
void WebViewImpl::loadData(const Data &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL)
{
if (_createSucceeded)
{
std::string dataString(reinterpret_cast<char *>(data.getBytes()), static_cast<unsigned int>(data.getSize()));
_systemWebControl->loadData(dataString, MIMEType, encoding, baseURL);
}
}
void WebViewImpl::loadHTMLString(const std::string &string, const std::string &baseURL)
{
if (_createSucceeded)
{
_systemWebControl->loadHTMLString(string, baseURL);
}
}
void WebViewImpl::loadUrl(const std::string &url)
{
if (_createSucceeded)
{
_systemWebControl->loadUrl(url);
}
}
void WebViewImpl::loadFile(const std::string &fileName)
{
if (_createSucceeded)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
_systemWebControl->loadFile(fullPath);
}
}
void WebViewImpl::stopLoading()
{
if (_createSucceeded)
{
_systemWebControl->stopLoading();
}
}
void WebViewImpl::reload()
{
if (_createSucceeded)
{
_systemWebControl->reload();
}
}
bool WebViewImpl::canGoBack()
{
if (_createSucceeded)
{
return _systemWebControl->canGoBack();
}
return false;
}
bool WebViewImpl::canGoForward()
{
if (_createSucceeded)
{
return _systemWebControl->canGoForward();
}
return false;
}
void WebViewImpl::goBack()
{
if (_createSucceeded)
{
_systemWebControl->goBack();
}
}
void WebViewImpl::goForward()
{
if (_createSucceeded)
{
_systemWebControl->goForward();
}
}
void WebViewImpl::setJavascriptInterfaceScheme(const std::string &scheme)
{
if (_createSucceeded)
{
_systemWebControl->setJavascriptInterfaceScheme(scheme);
}
}
void WebViewImpl::evaluateJS(const std::string &js)
{
if (_createSucceeded)
{
_systemWebControl->evaluateJS(js);
}
}
void WebViewImpl::setScalesPageToFit(const bool scalesPageToFit)
{
if (_createSucceeded)
{
_systemWebControl->setScalesPageToFit(scalesPageToFit);
}
}
void WebViewImpl::draw(Renderer *renderer, Mat4 const &transform, uint32_t flags)
{
if (_createSucceeded && (flags & Node::FLAGS_TRANSFORM_DIRTY))
{
Director *directorInstance = cocos2d::Director::getInstance();
GLView *glView = directorInstance->getOpenGLView();
const Size &frameSize = glView->getFrameSize();
const Size &winSize = directorInstance->getWinSize();
Vec2 leftBottom = this->_webView->convertToWorldSpace(Point::ZERO);
Vec2 rightTop = this->_webView->convertToWorldSpace(Point(_webView->getContentSize().width, _webView->getContentSize().height));
float uiLeft = frameSize.width / 2 + (leftBottom.x - winSize.width / 2) * glView->getScaleX();
float uiTop = frameSize.height / 2 - (rightTop.y - winSize.height / 2) * glView->getScaleY();
_systemWebControl->setWebViewRect(uiLeft, uiTop,
(rightTop.x - leftBottom.x) * glView->getScaleX(),
(rightTop.y - leftBottom.y) * glView->getScaleY());
}
}
void WebViewImpl::setVisible(bool visible)
{
if (_createSucceeded)
{
_systemWebControl->setWebViewVisible(visible);
}
}
} // namespace ui
} // namespace experimental
} //namespace cocos2d
//
// Implement Win32WebControl
//
bool Win32WebControl::s_isInitialized = false;
CComModule Win32WebControl::s_module;
void Win32WebControl::lazyInit()
{
HWND hwnd = cocos2d::Director::getInstance()->getOpenGLView()->getWin32Window();
LONG style = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, style | WS_CLIPCHILDREN);
HINSTANCE hInstance = GetModuleHandle(NULL);
CoInitialize(NULL);
s_module.Init(NULL, hInstance);
AtlAxWinInit();
}
static HGLOBAL globalAllocWstringFromString(const std::string &str)
{
int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
if (len <= 0)
{
return NULL;
}
HGLOBAL wstr = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, (len + 1) * sizeof(WCHAR));
if (wstr == NULL)
{
return NULL;
}
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, (WCHAR *)wstr, len);
return wstr;
}
static std::string bstr2string(BSTR bstr)
{
wchar_t *str = OLE2W(bstr);
std::string ret;
int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
if (len > 0)
{
HGLOBAL utf8Str = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, len + 1);
if (utf8Str != NULL)
{
WideCharToMultiByte(CP_UTF8, 0, str, -1, (char *)utf8Str, len, NULL, NULL);
ret.assign((char *)utf8Str);
GlobalFree(utf8Str);
}
}
return ret;
}
static bool isUrlJs(BSTR url)
{
return wcsncmp(OLE2W(url), L"javascript:", 11) == 0;
}
Win32WebControl::Win32WebControl()
: _webBrowser2(NULL)
, _connectionPoint(NULL)
, _htmlDoc(NULL)
, _goBackEnabled(true)
, _goForwardEnabled(true)
, _cookie(0)
, _reference(0)
, _shouldStartLoading(nullptr)
, _didFinishLoading(nullptr)
, _didFailLoading(nullptr)
{
if (!s_isInitialized)
{
lazyInit();
}
}
bool Win32WebControl::createWebView(
const std::function<bool (const std::string &)> &shouldStartLoading,
const std::function<void (const std::string &)> &didFinishLoading,
const std::function<void (const std::string &)> &didFailLoading,
const std::function<void (const std::string &)> &onJsCallback)
{
bool ret = false;
IConnectionPointContainer *container = NULL;
do
{
HWND hwnd = cocos2d::Director::getInstance()->getOpenGLView()->getWin32Window();
_winContainer.Create(hwnd, NULL, NULL, WS_CHILD | WS_VISIBLE);
HRESULT hr;
hr = _winContainer.CreateControl(L"shell.Explorer.2");
CC_BREAK_IF(FAILED(hr));
hr = _winContainer.QueryControl(__uuidof(IWebBrowser2), (void **)&_webBrowser2);
CC_BREAK_IF(FAILED(hr) || _webBrowser2 == NULL);
_webBrowser2->put_Silent(VARIANT_TRUE);
VARIANT var;
VariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(L"about:blank");
hr = _webBrowser2->Navigate2(&var, NULL, NULL, NULL, NULL);
SysFreeString(var.bstrVal);
VariantClear(&var);
CC_BREAK_IF(FAILED(hr));
hr = _webBrowser2->QueryInterface(IID_IConnectionPointContainer, (void **)&container);
CC_BREAK_IF(FAILED(hr));
hr = container->FindConnectionPoint(DIID_DWebBrowserEvents2, &_connectionPoint);
CC_BREAK_IF(FAILED(hr));
hr = _connectionPoint->Advise(this, &_cookie);
CC_BREAK_IF(FAILED(hr));
hr = _webBrowser2->get_Document(&_htmlDoc);
CC_BREAK_IF(FAILED(hr));
ret = true;
} while (0);
if (!ret)
{
removeWebView();
}
if (container != NULL)
{
container->Release();
container = NULL;
}
_shouldStartLoading = shouldStartLoading;
_didFinishLoading = didFinishLoading;
_didFailLoading = didFailLoading;
_onJsCallback = onJsCallback;
return ret;
}
void Win32WebControl::removeWebView()
{
if (_connectionPoint != NULL)
{
_connectionPoint->Unadvise(_cookie);
_connectionPoint->Release();
_connectionPoint = NULL;
}
if (_htmlDoc != NULL)
{
_htmlDoc->Release();
_htmlDoc = NULL;
}
if (_webBrowser2 != NULL)
{
_webBrowser2->Release();
_webBrowser2 = NULL;
}
_winContainer.DestroyWindow();
}
void Win32WebControl::setWebViewRect(const int left, const int top, const int width, const int height)
{
_winContainer.MoveWindow(left, top, width, height);
}
void Win32WebControl::setJavascriptInterfaceScheme(const std::string &scheme) const
{
}
void Win32WebControl::loadData(const std::string &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL) const
{
}
void Win32WebControl::loadHTMLString(const std::string &html, const std::string &baseURL)
{
//if (baseURL.empty())
//{
_loadHTMLString(html);
//}
//else
//{
// _htmlWillLoad = html;
// loadUrl(baseURL);
//}
}
void Win32WebControl::_loadHTMLString(const std::string &html) const
{
bool flag = false;
HGLOBAL htmlText = globalAllocWstringFromString(html);
if (htmlText != NULL)
{
IStream *stream = NULL;
if (SUCCEEDED(CreateStreamOnHGlobal(htmlText, FALSE, &stream)))
{
IPersistStreamInit *persistStreamInit = NULL;
if (SUCCEEDED(_htmlDoc->QueryInterface(IID_IPersistStreamInit, (void **)&persistStreamInit)))
{
if (SUCCEEDED(persistStreamInit->InitNew()) && SUCCEEDED(persistStreamInit->Load(stream)))
{
flag = true;
}
persistStreamInit->Release();
}
stream->Release();
}
GlobalFree(htmlText);
}
if (flag)
{
if (_didFinishLoading != nullptr)
{
std::string str("data:text/html,");
str.append(html);
_didFinishLoading(str);
}
}
else
{
if (_didFailLoading != nullptr)
{
std::string str("data:text/html,");
str.append(html);
_didFailLoading(str);
}
}
}
void Win32WebControl::loadUrl(BSTR url) const
{
VARIANT var;
VariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = url;
_webBrowser2->Navigate2(&var, NULL, NULL, NULL, NULL);
VariantClear(&var);
}
void Win32WebControl::loadUrl(const std::wstring &url) const
{
BSTR bstr = SysAllocString(url.c_str());
loadUrl(bstr);
SysFreeString(bstr);
}
void Win32WebControl::loadUrl(const std::string &url) const
{
HGLOBAL unicodeStr = globalAllocWstringFromString(url);
if (unicodeStr != NULL)
{
loadUrl(std::wstring((WCHAR *)unicodeStr));
GlobalFree(unicodeStr);
}
}
void Win32WebControl::loadFile(const std::string &filePath) const
{
HGLOBAL unicodeStr = globalAllocWstringFromString(filePath);
if (unicodeStr != NULL)
{
loadUrl(std::wstring((WCHAR *)unicodeStr));
GlobalFree(unicodeStr);
}
}
void Win32WebControl::stopLoading() const
{
_webBrowser2->Stop();
}
void Win32WebControl::reload() const
{
_webBrowser2->Refresh();
}
bool Win32WebControl::canGoBack() const
{
return _goBackEnabled;
}
bool Win32WebControl::canGoForward() const
{
return _goForwardEnabled;
}
void Win32WebControl::goBack() const
{
_webBrowser2->GoBack();
}
void Win32WebControl::goForward() const
{
_webBrowser2->GoForward();
}
void Win32WebControl::evaluateJS(const std::string &js) const
{
std::string url("javascript:");
url.append(js);
loadUrl(url);
}
void Win32WebControl::setScalesPageToFit(const bool scalesPageToFit) const
{
}
void Win32WebControl::setWebViewVisible(const bool visible) const
{
_webBrowser2->put_Visible(visible ? VARIANT_TRUE : VARIANT_FALSE);
}
// Implement IUnknown
HRESULT STDMETHODCALLTYPE Win32WebControl::QueryInterface(REFIID riid, void **ppvObject)
{
BOOL isBadPtr = FALSE;
CCASSERT(!(isBadPtr = IsBadWritePtr(ppvObject, sizeof(void *))), "");
if (isBadPtr)
{
return E_POINTER;
}
*ppvObject = NULL;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch) || IsEqualIID(riid, DIID_DWebBrowserEvents2))
{
AddRef();
*ppvObject = this;
return S_OK;
}
return E_NOINTERFACE;
}
ULONG STDMETHODCALLTYPE Win32WebControl::AddRef(void)
{
InterlockedIncrement(&_reference);
return _reference;
}
ULONG STDMETHODCALLTYPE Win32WebControl::Release(void)
{
CCASSERT(_reference > 0, "reference count should greater than 0");
InterlockedDecrement(&_reference);
// do not delete this if _reference == 0, otherwise, it will crash when call removeWebView
return _reference;
}
// Implement IDispatch
HRESULT STDMETHODCALLTYPE Win32WebControl::GetTypeInfoCount(UINT *pctinfo)
{
*pctinfo = 0;
return S_OK;
}
HRESULT STDMETHODCALLTYPE Win32WebControl::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
UNREFERENCED_PARAMETER(iTInfo);
UNREFERENCED_PARAMETER(lcid);
*ppTInfo = NULL;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE Win32WebControl::GetIDsOfNames(
REFIID riid,
LPOLESTR *rgszNames,
UINT cNames,
LCID lcid,
DISPID *rgDispId)
{
UNREFERENCED_PARAMETER(riid);
UNREFERENCED_PARAMETER(rgszNames);
UNREFERENCED_PARAMETER(cNames);
UNREFERENCED_PARAMETER(lcid);
UNREFERENCED_PARAMETER(rgDispId);
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE Win32WebControl::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr)
{
if (!IsEqualIID(riid, IID_NULL)) // riid should always be IID_NULL
{
return DISP_E_UNKNOWNINTERFACE;
}
switch (dispIdMember)
{
case DISPID_COMMANDSTATECHANGE:
if (pDispParams != NULL && pDispParams->cArgs == 2)
{
const VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[0].vt == VT_BOOL && rgvarg[1].vt == VT_I4)
{
switch (rgvarg[1].intVal)
{
case CSC_NAVIGATEFORWARD:
_goForwardEnabled = (rgvarg[0].boolVal != VARIANT_FALSE); // VARIANT_TRUE is -1
return S_OK;
case CSC_NAVIGATEBACK:
_goBackEnabled = (rgvarg[0].boolVal != VARIANT_FALSE); // VARIANT_TRUE is -1
return S_OK;
default:
break;
}
}
}
break;
case DISPID_BEFORENAVIGATE2:
if (pDispParams != NULL && pDispParams->cArgs == 7)
{
VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[6].vt == VT_DISPATCH && rgvarg[6].pdispVal == _webBrowser2)
{
if (rgvarg[0].vt == (VT_BYREF | VT_BOOL) && rgvarg[5].vt == (VT_BYREF | VT_VARIANT))
{
VARIANT_BOOL *cancel = rgvarg[0].pboolVal;
BSTR url = rgvarg[5].pvarVal->bstrVal;
*cancel = VARIANT_FALSE;
if (isUrlJs(url))
{
if (_onJsCallback != nullptr)
{
_onJsCallback(bstr2string(url));
}
}
else
{
if (_shouldStartLoading != nullptr)
{
*cancel = _shouldStartLoading(bstr2string(url)) ? VARIANT_FALSE : VARIANT_TRUE; // VARIANT_TRUE is -1
}
}
return S_OK;
}
}
}
break;
case DISPID_DOCUMENTCOMPLETE:
if (pDispParams != NULL && pDispParams->cArgs == 2)
{
const VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[1].vt == VT_DISPATCH && rgvarg[1].pdispVal == _webBrowser2 && rgvarg[0].vt == (VT_BYREF | VT_VARIANT))
{
READYSTATE state;
if (SUCCEEDED(_webBrowser2->get_ReadyState(&state)) && state == READYSTATE_COMPLETE)
{
BSTR url = rgvarg[0].pvarVal->bstrVal;
if (_didFinishLoading != nullptr && !isUrlJs(url)) // ignore js
{
_didFinishLoading(bstr2string(url));
}
if (!_htmlWillLoad.empty())
{
_loadHTMLString(_htmlWillLoad);
_htmlWillLoad.clear();
}
return S_OK;
}
}
}
break;
case DISPID_NAVIGATECOMPLETE2:
if (pDispParams != NULL && pDispParams->cArgs == 2)
{
const VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[1].vt == VT_DISPATCH && rgvarg[1].pdispVal == _webBrowser2)
{
if (rgvarg[0].vt == (VT_BYREF | VT_VARIANT))
{
BSTR url = rgvarg[0].pvarVal->bstrVal;
return S_OK;
}
}
}
break;
case DISPID_NAVIGATEERROR:
if (pDispParams != NULL && pDispParams->cArgs == 5)
{
const VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[4].vt == VT_DISPATCH && rgvarg[4].pdispVal == _webBrowser2)
{
if (rgvarg[3].vt == (VT_BYREF | VT_VARIANT) && rgvarg[1].vt == (VT_BYREF | VT_VARIANT) && rgvarg[0].vt == (VT_BYREF | VT_BOOL))
{
VARIANT_BOOL *cancel = rgvarg[0].pboolVal;
HRESULT codes = rgvarg[1].pvarVal->lVal;
BSTR url = rgvarg[3].pvarVal->bstrVal;
if (_didFailLoading != nullptr && !isUrlJs(url)) // ignore js
{
_didFailLoading(bstr2string(url));
}
*cancel = VARIANT_FALSE;
return S_OK;
}
}
}
break;
case DISPID_PROGRESSCHANGE:
if (pDispParams != NULL && pDispParams->cArgs == 2)
{
const VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[0].vt == VT_I4 && rgvarg[1].vt == VT_I4)
{
LONG maxProgress = rgvarg[0].lVal;
LONG curProgress = rgvarg[1].lVal;
return S_OK;
}
}
break;
case DISPID_NEWWINDOW2:
if (pDispParams != NULL && pDispParams->cArgs == 2)
{
const VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[0].vt == (VT_BYREF | VT_BOOL) && rgvarg[1].vt == (VT_BYREF | VT_DISPATCH))
{
VARIANT_BOOL *cancel = rgvarg[0].pboolVal;
IDispatch **dis = rgvarg[1].ppdispVal;
*dis = NULL;
*cancel = VARIANT_TRUE; // forbit to create new window
return S_OK;
}
}
break;
case DISPID_NEWWINDOW3:
if (pDispParams != NULL && pDispParams->cArgs == 5)
{
const VARIANTARG *rgvarg = pDispParams->rgvarg;
if (rgvarg[0].vt == VT_BSTR && rgvarg[1].vt == VT_BSTR && rgvarg[2].vt == VT_I4
&& rgvarg[3].vt == (VT_BYREF | VT_BOOL) && rgvarg[4].vt == (VT_BYREF | VT_DISPATCH))
{
BSTR url = rgvarg[0].bstrVal;
BSTR urlContext = rgvarg[1].bstrVal;
LONG flags = rgvarg[2].lVal;
VARIANT_BOOL *cancel = rgvarg[3].pboolVal;
IDispatch **dis = rgvarg[4].ppdispVal;
*dis = NULL;
*cancel = VARIANT_TRUE; // forbit to create new window
loadUrl(url);
return S_OK;
}
}
break;
default:
break;
}
return E_NOTIMPL;
}
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32

View File

@ -0,0 +1,65 @@
#ifndef __cocos2d_plugin_WebViewImpl_win32_H_
#define __cocos2d_plugin_WebViewImpl_win32_H_
#include "platform/CCPlatformConfig.h"
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include <string>
#include "CCStdC.h"
namespace cocos2d {
class Data;
class Renderer;
class Mat4;
namespace experimental {
namespace ui {
class WebView;
}
}
}
class Win32WebControl;
namespace cocos2d {
namespace experimental {
namespace ui {
class WebViewImpl
{
public:
WebViewImpl(cocos2d::experimental::ui::WebView *webView);
virtual ~WebViewImpl();
void setJavascriptInterfaceScheme(const std::string &scheme);
void loadData(const cocos2d::Data &data, const std::string &MIMEType, const std::string &encoding, const std::string &baseURL);
void loadHTMLString(const std::string &string, const std::string &baseURL);
void loadUrl(const std::string &url);
void loadFile(const std::string &fileName);
void stopLoading();
void reload();
bool canGoBack();
bool canGoForward();
void goBack();
void goForward();
void evaluateJS(const std::string &js);
void setScalesPageToFit(const bool scalesPageToFit);
virtual void draw(cocos2d::Renderer *renderer, cocos2d::Mat4 const &transform, uint32_t flags);
virtual void setVisible(bool visible);
private:
bool _createSucceeded;
Win32WebControl *_systemWebControl;
WebView *_webView;
};
} // namespace ui
} // namespace experimental
} //cocos2d
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#endif //__cocos2d_plugin_WebViewImpl_win32_H_
#endif

View File

@ -20,6 +20,8 @@
#include "UIFocusTest/UIFocusTest.h" #include "UIFocusTest/UIFocusTest.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#include "UIVideoPlayerTest/UIVideoPlayerTest.h" #include "UIVideoPlayerTest/UIVideoPlayerTest.h"
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "UIWebViewTest/UIWebViewTest.h" #include "UIWebViewTest/UIWebViewTest.h"
#endif #endif
#include "UIScale9SpriteTest.h" #include "UIScale9SpriteTest.h"
@ -105,6 +107,8 @@ static const char* s_testArray[] =
"UIFocusTest-ListView", "UIFocusTest-ListView",
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
"UIVideoPlayerTest", "UIVideoPlayerTest",
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
"UIWebViewTest", "UIWebViewTest",
#endif #endif
"UIScale9SpriteTest", "UIScale9SpriteTest",
@ -346,6 +350,8 @@ Scene *UISceneManager::currentUIScene()
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
case kUIVideoPlayerTest: case kUIVideoPlayerTest:
return VideoPlayerTest::sceneWithTitle(s_testArray[_currentUISceneId]); return VideoPlayerTest::sceneWithTitle(s_testArray[_currentUISceneId]);
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
case KWebViewTest: case KWebViewTest:
return WebViewTest::sceneWithTitle(s_testArray[_currentUISceneId]); return WebViewTest::sceneWithTitle(s_testArray[_currentUISceneId]);
#endif #endif

View File

@ -96,6 +96,8 @@ enum
kUIFocusTest_ListView, kUIFocusTest_ListView,
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
kUIVideoPlayerTest, kUIVideoPlayerTest,
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
KWebViewTest, KWebViewTest,
#endif #endif
kUIScale9SpriteTest, kUIScale9SpriteTest,

View File

@ -147,20 +147,20 @@ bool WebViewTest::init()
return false; return false;
} }
bool WebViewTest::onWebViewShouldStartLoading(experimental::ui::WebView *sender, std::string url) bool WebViewTest::onWebViewShouldStartLoading(experimental::ui::WebView *sender, const std::string &url)
{ {
CCLOG("onWebViewShouldStartLoading, url is %s", url.c_str()); CCLOG("onWebViewShouldStartLoading, url is %s", url.c_str());
return true; return true;
} }
void WebViewTest::onWebViewDidFinishLoading(experimental::ui::WebView *sender, std::string url) void WebViewTest::onWebViewDidFinishLoading(experimental::ui::WebView *sender, const std::string &url)
{ {
CCLOG("onWebViewDidFinishLoading, url is %s", url.c_str()); CCLOG("onWebViewDidFinishLoading, url is %s", url.c_str());
} }
void WebViewTest::onWebViewDidFailLoading(experimental::ui::WebView *sender, std::string url) void WebViewTest::onWebViewDidFailLoading(experimental::ui::WebView *sender, const std::string &url)
{ {
CCLOG("onWebViewDidFailLoading, url is %s", url.c_str()); CCLOG("onWebViewDidFailLoading, url is %s", url.c_str());

View File

@ -37,9 +37,9 @@ public:
UI_SCENE_CREATE_FUNC(WebViewTest); UI_SCENE_CREATE_FUNC(WebViewTest);
virtual bool init(); virtual bool init();
bool onWebViewShouldStartLoading(experimental::ui::WebView *sender, std::string url); bool onWebViewShouldStartLoading(experimental::ui::WebView *sender, const std::string &url);
void onWebViewDidFinishLoading(experimental::ui::WebView *sender, std::string url); void onWebViewDidFinishLoading(experimental::ui::WebView *sender, const std::string &url);
void onWebViewDidFailLoading(experimental::ui::WebView *sender, std::string url); void onWebViewDidFailLoading(experimental::ui::WebView *sender, const std::string &url);
private: private: